Unity控制逻辑(移动,翻滚,瞬移)

2023-10-31 12:31

本文主要是介绍Unity控制逻辑(移动,翻滚,瞬移),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

1.案例的前期准备

2.移动的实现

3.翻滚的实现

4.瞬移的实现


1.案例的前期准备

1.创建2D项目

 2.搭建场景

分别创建player(玩家),background(背景图),barrier(障碍物)。

 3.创建C#脚本

在对象player上创建CharacterController2D脚本

2.移动的实现

public class CharacterController2D : MonoBehaviour
{private const float MOVE_SPEED = 5f;private void Awake(){rigidbody2D = GetComponent<Rigidbody2D>();}private void Update(){float moveX = 0f;float moveY = 0f;if (Input.GetKey(KeyCode.W)){// transform.position += new Vector3(0,+1);moveY = +1f;}if (Input.GetKey(KeyCode.S)){// transform.position += new Vector3(0,-1);moveY = -1f;}if (Input.GetKey(KeyCode.A)){// transform.position += new Vector3(-1,0);moveX = -1f;}if (Input.GetKey(KeyCode.D)){// transform.position += new Vector3(+1,0);moveX = +1f;}moveDir = new Vector3(moveX, moveY).normalized;}private void FixedUpdate(){rigidbody2D.velocity = moveDir * MOVE_SPEED;}
}

实现方法:方向向量*移动速度

1,使用const储存物体速度(float)

2,在Update()中使用Input.GetKey(keyCode.按键)方法读取玩家相应按键 

3,使用moveX,moveY分别保存在X,Y轴的移动增量,以此创建Vector

4,使用normalized获取Vector对象的方向向量(单位向量)赋给moveDir              

Rigidbody2D.velocity

描述

刚体的线性速度,采用单位/秒形式。

在移动或旋转一个物体时,往往会直接使用Transform来执行这些操作。这种方法对于不具物理特性的GameObject来说,是可行的。但是一旦GameObject上附带有Rigidbody2D,这种方式就会带来性能的损失

3.翻滚的实现

public class CharacterController2D : MonoBehaviour
{//构建枚举类区分行走状态和翻滚状态private enum State{Normal, //正常行走Rolling, //翻滚}[SerializeField] private LayerMask dashLayerMask;private Rigidbody2D rigidbody2D;private Vector3 moveDir;private Vector3 rollDir; //翻滚的方向private Vector3 lastMoveDir; //保存最后一次非静止状态的Vectorprivate float rollSpeed; //翻滚的初始速度private State state; private void Awake(){rigidbody2D = GetComponent<Rigidbody2D>();state = State.Normal;}private void Update(){switch (state){case State.Normal:float moveX = 0f;float moveY = 0f;if (Input.GetKey(KeyCode.W)){// transform.position += new Vector3(0,+1);moveY = +1f;}if (Input.GetKey(KeyCode.S)){// transform.position += new Vector3(0,-1);moveY = -1f;}if (Input.GetKey(KeyCode.A)){// transform.position += new Vector3(-1,0);moveX = -1f;}if (Input.GetKey(KeyCode.D)){// transform.position += new Vector3(+1,0);moveX = +1f;}moveDir = new Vector3(moveX, moveY).normalized;//保存最后一次非静止状态的Vector,防止原地翻滚if(moveX != 0f || moveY != 0){lastMoveDir = moveDir;}//按下空格键进入翻滚状态   if (Input.GetKey(KeyCode.Space)){//最后一次非静止状态的Vector,即翻滚的方向rollDir = lastMoveDir;//翻滚的初始速度rollSpeed = 25f;state = State.Rolling;}break;case State.Rolling://翻滚是一个减速过程//减速系数float rollSpeedDropMultiplier = 5f;//按帧减速rollSpeed -= rollSpeed * rollSpeedDropMultiplier * Time.deltaTime;//设置下限float rollSpeedMinimum = 5f;//小于下限切换至行走状态if(rollSpeed < rollSpeedMinimum){state=State.Normal;}break;}}private void FixedUpdate(){switch (state){case State.Normal:rigidbody2D.velocity = moveDir * MOVE_SPEED;break;case State.Rolling:rigidbody2D.velocity = rollDir * rollSpeed;break;}}
}

4.瞬移的实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class CharacterController2D : MonoBehaviour
{private const float MOVE_SPEED = 5f;private enum State{Normal,Rolling,}[SerializeField] private LayerMask dashLayerMask;//设置射线与哪些层级发生碰撞,此项为可序列化的private Rigidbody2D rigidbody2D;private Vector3 moveDir;private Vector3 rollDir;private Vector3 lastMoveDir;private float rollSpeed;private bool isDashButtonDown;//瞬移状态切换private State state;private void Awake(){rigidbody2D = GetComponent<Rigidbody2D>();state = State.Normal;}private void Update(){switch (state){case State.Normal:float moveX = 0f;float moveY = 0f;if (Input.GetKey(KeyCode.W)){// transform.position += new Vector3(0,+1);moveY = +1f;}if (Input.GetKey(KeyCode.S)){// transform.position += new Vector3(0,-1);moveY = -1f;}if (Input.GetKey(KeyCode.A)){// transform.position += new Vector3(-1,0);moveX = -1f;}if (Input.GetKey(KeyCode.D)){// transform.position += new Vector3(+1,0);moveX = +1f;}moveDir = new Vector3(moveX, moveY).normalized;if(moveX != 0f || moveY != 0){lastMoveDir = moveDir;}//按F进入瞬移状态if (Input.GetKey(KeyCode.F)){isDashButtonDown = true;}if (Input.GetKey(KeyCode.Space)){rollDir = lastMoveDir;rollSpeed = 25f;state = State.Rolling;}break;case State.Rolling:float rollSpeedDropMultiplier = 5f;rollSpeed -= rollSpeed * rollSpeedDropMultiplier * Time.deltaTime;float rollSpeedMinimum = 5f;if(rollSpeed < rollSpeedMinimum){state=State.Normal;}break;}}private void FixedUpdate(){switch (state){case State.Normal:rigidbody2D.velocity = moveDir * MOVE_SPEED;if (isDashButtonDown){//瞬移距离float dashAmount = 0.5f;//无障碍物情况下的瞬移量Vector3 dashPosition = transform.position + lastMoveDir * dashAmount;//使用射线判断瞬移路径上是否有障碍物,有则被阻碍RaycastHit2D raycastHit2D = Physics2D.Raycast(transform.position, lastMoveDir, dashAmount, dashLayerMask);//射线碰撞的物体不为空if (raycastHit2D.collider != null){//射线与物体碰撞的点即为瞬移的最终位置dashPosition = raycastHit2D.point;}rigidbody2D.MovePosition(dashPosition);//切换至行走状态isDashButtonDown = false;}break;case State.Rolling:rigidbody2D.velocity = rollDir * rollSpeed;break;}}
}

​​​RigidBody2D.MovePosition

描述

将刚体移动到 /position/。

通过计算在下一次物理更新期间将刚体移动到指定 position 所需的适当线速度来将刚体移动到该位置。在移动过程中,重力或线性阻力都不会影响刚体。这使得对象能够快速从现有位置穿过世界移动到指定的 /position/。

由于该功能允许刚体穿过世界快速移动到指定的 /position/,因此附加到刚体的任何碰撞体都将按预期作出反应,也就是说,它们将产生碰撞和/或触发。这也意味着如果碰撞体产生碰撞,则将影响到刚体的运动,并可能阻止刚体在下一次物理更新期间到达指定的 /position/。如果是运动刚体,则任何碰撞都不影响刚体本身,只会影响任何其他动态碰撞体。

2D 刚体对其移动速度有固定限制,因此在短时间内尝试移动较远的距离会导致刚体无法在下一次物理更新期间到达指定 /position/。建议仅将该函数用于相对较短距离的移动。

请务必注意, 实际的位置更改只在下一次物理更新期间进行, 因此重复调用该方法而不等待下一次物理更新将导致使用最后一次调用。 因此,建议在 FixedUpdate 回调期间调用该函数。

Rigidbody2D.velocity:将钢体线性移动至某一位置

RigidBody2D.MovePosition:将钢体线性瞬移至某一位置

如何理解本案例中的射线RaycastHit2D

若没有使用射线进行判定,这钢体可能可以穿越碰撞体

RaycastHit2D raycastHit2D = Physics2D.Raycast(transform.position, lastMoveDir, dashAmount, dashLayerMask);

本案例的射线分别有如下参数

1.射线的起始位置

2.射线的方向

3.射线的距离

4.射线应于哪些层级发生碰撞

ps:若不设置此项,则与所有层级发生碰撞。可能导致本案例中的瞬移无法实现

这篇关于Unity控制逻辑(移动,翻滚,瞬移)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/315377

相关文章

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

我在移动打工的日志

客户:给我搞一下录音 我:不会。不在服务范围。 客户:是不想吧 我:笑嘻嘻(气笑) 客户:小姑娘明明会,却欺负老人 我:笑嘻嘻 客户:那我交话费 我:手机号 客户:给我搞录音 我:不会。不懂。没搞过。 客户:那我交话费 我:手机号。这是电信的啊!!我这是中国移动!! 客户:我不管,我要充话费,充话费是你们的 我:可是这是移动!!中国移动!! 客户:我这是手机号 我:那又如何,这是移动!你是电信!!

用Unity2D制作一个人物,实现移动、跳起、人物静止和动起来时的动画:中(人物移动、跳起、静止动作)

上回我们学到创建一个地形和一个人物,今天我们实现一下人物实现移动和跳起,依次点击,我们准备创建一个C#文件 创建好我们点击进去,就会跳转到我们的Vision Studio,然后输入这些代码 using UnityEngine;public class Move : MonoBehaviour // 定义一个名为Move的类,继承自MonoBehaviour{private Rigidbo

控制反转 的种类

之前对控制反转的定义和解释都不是很清晰。最近翻书发现在《Pro Spring 5》(免费电子版在文章最后)有一段非常不错的解释。记录一下,有道翻译贴出来方便查看。如有请直接跳过中文,看后面的原文。 控制反转的类型 控制反转的类型您可能想知道为什么有两种类型的IoC,以及为什么这些类型被进一步划分为不同的实现。这个问题似乎没有明确的答案;当然,不同的类型提供了一定程度的灵活性,但

简单的角色响应鼠标而移动

actor类 //处理移动距离,核心是找到角色坐标在世界坐标的向量的投影(x,y,z),然后在世界坐标中合成,此CC是在地面行走,所以Y轴投影始终置为0; using UnityEngine; using System.Collections; public class actor : MonoBehaviour { public float speed=0.1f; CharacterCo

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理

深入解析秒杀业务中的核心问题 —— 从并发控制到事务管理 秒杀系统是应对高并发、高压力下的典型业务场景,涉及到并发控制、库存管理、事务管理等多个关键技术点。本文将深入剖析秒杀商品业务中常见的几个核心问题,包括 AOP 事务管理、同步锁机制、乐观锁、CAS 操作,以及用户限购策略。通过这些技术的结合,确保秒杀系统在高并发场景下的稳定性和一致性。 1. AOP 代理对象与事务管理 在秒杀商品

PostgreSQL中的多版本并发控制(MVCC)深入解析

引言 PostgreSQL作为一款强大的开源关系数据库管理系统,以其高性能、高可靠性和丰富的功能特性而广受欢迎。在并发控制方面,PostgreSQL采用了多版本并发控制(MVCC)机制,该机制为数据库提供了高效的数据访问和更新能力,同时保证了数据的一致性和隔离性。本文将深入解析PostgreSQL中的MVCC功能,探讨其工作原理、使用场景,并通过具体SQL示例来展示其在实际应用中的表现。 一、

vue2实践:el-table实现由用户自己控制行数的动态表格

需求 项目中需要提供一个动态表单,如图: 当我点击添加时,便添加一行;点击右边的删除时,便删除这一行。 至少要有一行数据,但是没有上限。 思路 这种每一行的数据固定,但是不定行数的,很容易想到使用el-table来实现,它可以循环读取:data所绑定的数组,来生成行数据,不同的是: 1、table里面的每一个cell,需要放置一个input来支持用户编辑。 2、最后一列放置两个b

逻辑表达式,最小项

目录 得到此图的逻辑电路 1.画出它的真值表 2.根据真值表写出逻辑式 3.画逻辑图 逻辑函数的表示 逻辑表达式 最小项 定义 基本性质 最小项编号 最小项表达式   得到此图的逻辑电路 1.画出它的真值表 这是同或的逻辑式。 2.根据真值表写出逻辑式   3.画逻辑图   有两种画法,1是根据运算优先级非>与>或得到,第二种是采

UMI复现代码运行逻辑全流程(一)——eval_real.py(尚在更新)

一、文件夹功能解析 全文件夹如下 其中,核心文件作用为: diffusion_policy:扩散策略核心文件夹,包含了众多模型及基础库 example:标定及配置文件 scripts/scripts_real:测试脚本文件,区别在于前者倾向于单体运行,后者为整体运行 scripts_slam_pipeline:orb_slam3运行全部文件 umi:核心交互文件夹,作用在于构建真