在Unity3D中,有多种方式可以改变物体的坐标,实现移动的目的,其本质是每帧修改物体的position。以下代码均手打检验过。
利用transform组件
方法一:直接给游戏物体(也就是脚本所挂物体)的坐标进行 ± 步长即可
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMove : MonoBehaviour {
// Use this for initialization
private Vector3 Pos;
void Start () {
Pos = transform.localPosition;
Debug.Log(Pos);
}
// Update is called once per frame
void Update ()
{
if (Input.GetKeyDown(KeyCode.A)|Input.GetKeyDown(KeyCode.LeftArrow))//判断用户输入的是否是W或者键盘的左键键
{
Pos = new Vector3(Pos.x - 1, Pos.y, Pos.z);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
else if (Input.GetKeyDown(KeyCode.D) | Input.GetKeyDown(KeyCode.RightArrow))//判断用户输入的是否是D或者右键
{
Pos = new Vector3(Pos.x + 1, Pos.y, Pos.z);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
else if (Input.GetKeyDown(KeyCode.W) | Input.GetKeyDown(KeyCode.UpArrow))//判断用户输入的是否是W或者是上键
{
Pos = new Vector3(Pos.x, Pos.y, Pos.z - 1);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
else if (Input.GetKeyDown(KeyCode.S) | Input.GetKeyDown(KeyCode.DownArrow))//判断用户输入的是否是S或者是下键
{
Pos = new Vector3(Pos.x, Pos.y, Pos.z + 1);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
else if (Input.GetKeyDown(KeyCode.Space))
{
Pos = new Vector3(Pos.x, Pos.y + 1, Pos.z);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
else if (Input.GetKeyUp(KeyCode.Space))
{
Pos = new Vector3(Pos.x, Pos.y - 1, Pos.z);
transform.localPosition = Pos;
Debug.Log(transform.localPosition);
}
}
}
方法二:通过transform.Translate(v);函数来控制坐标
即:
Unity this.transform.Translate(Vector3.down * moveSpeed * Time.deltaTime)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMove : MonoBehaviour {
// Use this for initialization
float speed = 1f;
void Start () {
}
// Update is called once per frame
void Update ()
{
float h = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
Vector3 v = new Vector3(h, 0, y);//构建新的移动变量可能是单方向也可能是两个方向
v = v.normalized;//方向的标准化,也可以说是取单位
v = v * speed * Time.deltaTime;//用Time.deltaTime来保证移动的每一帧速度都一样,不会因为帧数的大小而改变距离等
transform.Translate(v);//共有两个参数,前面确定的是移动的方向和距离,后面的是坐标系的类型可能是世界坐标系也有可能是以自身为坐标系
}
}
Time.delatime是本帧所用的时间,在前面的博客里面有解释过,假设这个值是个定值,那么也就是说Ts移动的单位距离是
MovespeedT,所以每秒的运动距离即为MovespeedT/T=Movespeed,而Movespeed是我们事先设置好的速度,也就是定值,这样就可以保证游戏物体每秒所移动的距离是个定值,不会随着帧数的改变而改变。
这两种方法共同之处就在于,必须要先获得键盘的相应,不同在于获取的方式不同,一个是通过Input.GetKey(),一个是通过Input.GetAxisRaw()获取。
注意:上面的两种方法都需要在Uodate方法中实现,切移动仅是二维坐标系上。
方法三:平滑的移动
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReboundMove : MonoBehaviour
{
// Use this for initialization
public float speed;
public float xMin;
public float xMax;
void Start () {
}
// Update is called once per frame
void Update()
{
float hor = Input.GetAxisRaw("Horizontal");//不会有一个速度渐变的过程而GetAxis(“”)有一个渐变的过程不是很适合我们
//float ver = Input.GetAxis("")
if (hor != 0)
{
Vector3 pos = transform.position;
pos.x -= pos.x * speed * hor * Time.deltaTime;
pos.x = Mathf.Clamp(pos.x, xMin, xMax);//限制x的范围
//或者写成判断的形式
pos.x -= pos.x * speed * hor * Time.deltaTime;
transform.position = pos;
}
}
}
通过Rigibody组件
方法一:通过Rigibody类中的velocity方法控制
代码如下:
using System.Collections.Generic;
using UnityEngine;
public class SphereMove : MonoBehaviour {
// Use this for initialization
public Rigidbody Sp;
private float speed = 10f;
void Start () {
Sp = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update ()
{
float h = Input.GetAxis("Horizontal");
float y = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.W) | Input.GetKeyDown(KeyCode.S))
{
Sp.velocity = Vector3.forward * y * speed ;
}
if (Input.GetKeyDown(KeyCode.A) | Input.GetKeyDown(KeyCode.D))
{
Sp.velocity = Vector3.right * h * speed ;
}
}
}
这里需要注意的是:由于最开始的速度基数是零,所以游戏开始运行时,他是静止的,当你按下控制方向的键时,它会给游戏物体添加相应方向的速度,这个速度既有大小又有方向,也就是速度向量,并且这个速度向量是会叠加的,在添加刚体组件之后,记得考虑摩擦力,按下的瞬间,物体的速度的确是你设置的值,但是由于有摩擦力,会使速度变慢,当连续点击的时候他的速度叠加之后会变得很大。如果想要取消摩擦力,添加一个物理材质,在物理材质里面有取消摩擦力的选项。
Dynamic Friction 滑动摩擦
3: Static Firction 静态摩擦
4: Bounciness 表面弹性;
5: Friction Combine 摩擦力的混合方式
6: Bounciness Combine 弹力的混合方式;,Average就是每次弹完就取平均值,慢慢停下来
方法二:通过添加力来控制,即Rigidbody.AddForce()方法
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SphereMove : MonoBehaviour {
// Use this for initialization
public Rigidbody Sp;//获取游戏物体的刚体组件
public float Factor = 1f;//设定速度基数
void Start ()
{
Sp = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update ()
{
float horizontal = Input.GetAxis("Horizontal");//判断用户输入
float vertical = Input.GetAxis("Vertical");
if (Input.GetKeyDown(KeyCode.W) | Input.GetKeyDown(KeyCode.S))
{
Sp.AddForce(Vector3.forward * Factor* vertical , ForceMode.Impulse);
}
else if (Input.GetKeyDown(KeyCode.A) | Input.GetKeyDown(KeyCode.D))
{
Sp.AddForce(Vector3.right * horizontal * Factor, ForceMode.Impulse);
}
}
}

本文详细介绍在Unity3D中实现物体移动的多种方法,包括直接修改坐标、使用Translate函数和平滑移动,以及通过Rigidbody组件控制物体移动,提供代码示例并解析不同方法的特点。
15万+

被折叠的 条评论
为什么被折叠?



