# Unity 3D 移動
### 第一種transform.Translate的移動方式
[ transform.Translate的移動方式](https://youtube.com/shorts/32lUwDPensc?feature=shareshare)
在Update直接移動物體,產生位移
移動速度快,但動起來不自然,同時容易產生破圖
```C#=
public GameObject player;
public float playerSpeed=0.1f;
void Move()
{
if (Input.GetKey(KeyCode.W))
{
transform.Translate(Vector3.forward * -playerSpeed);
}
if (Input.GetKey(KeyCode.S))
{
transform.Translate(Vector3.forward * playerSpeed);
}
if (Input.GetKey(KeyCode.A))
{
transform.Translate(Vector3.right * playerSpeed);
}
if (Input.GetKey(KeyCode.D))
{
transform.Translate(Vector3.forward * playerSpeed);
}
}
private void FixedUpdate()
{
Move();
}
//但動起來過快,而且容易破圖
```
### 第二種 Add force的移動方式
[ Add force的移動方式](https://youtube.com/shorts/teSZvE1dAJA?feature=share)
Input.GetAxis適合水平跟垂直的方向(WASD),與input system的差別在獲取輸入方式的值不同
並使用到了rigibody,並用AddForce()方法模擬施加外力,用物理引擎處理移動,並非直接改變物體位置,必須有rigibody才能用AddForce()。速度被物體自身的質量被影響。
FixedUpdate()每隔一段時間才會更新,Update則是每幀,如果將ProcessInput()放在FixedUpdate(),鍵盤輸入會被每隔一段時間才被讀取。會出現按下鍵盤但不會移動的狀況
(因為某些輸入被錯過了,所以無法更新狀態)。
AddForce所施加的力不受物體方向影響,例如重力
```C#=
public GameObject player;
public float playerSpeed=0.1f;
private float xInput;
private float zInput;
public Rigidbody rb;
//讀取玩家輸入,並存在xInput還有zInput
void ProcessInput()
{
xInput = Input.GetAxis("Horizontal");//Input system預設的字
zInput = Input.GetAxis("Vertical");
}
void Move()
{
rb.AddForce(new Vector3(xInput, 0.0f, zInput) * playerSpeed);//unity3D裡y會更像跳躍
}
private void Update()
{
ProcessInput();
}
// Update is called once per frame
private void FixedUpdate()
{
Move();
}
```
### 二之一 AddRelativeForce()
它根據物體當前的方向施加力。施加的力與方向有關,與AddForce最大的不同在於施加的力跟"方向"有關。例如火箭推進器的力,熱氣球的熱氣流帶動氣球往上的力。
```C#=
if(Input.GetKey(KeyCode.Space))
{
rb.AddRelativeForce(Vector3.up * mainThrust * Time.deltaTime);
}
```
### 二之二 transform.localPosition.x
父物體移動,子物體也能順利動的方法
transform.localPosition.x是將父物體的位置當成(0,0,0,)後面所有子物體的座標以此為參考,能夠確認該物體移動時,他所有的子物體也會一起動
程式在執行的時候可以當成一種綁定位置,使之移動,或是其他編寫腳本時,所有物體的位置都能維持我們想要的樣子
若使用transform.position,所有的物體位置會到世界統座標下的位置,各prefab位置會錯亂
與先前第二種類似
```
public class PlayerMoveControl : MonoBehaviour
{
float xInput;
float zInput;
[SerializeField] float UserMoveSpeed=10f;
void Update()
{
ProcessInput();
Move();
}
void ProcessInput()
{
xInput = Input.GetAxis("Horizontal");
zInput = Input.GetAxis("Vertical");
}
//A D鍵移動
// transform.localPosition.x是將父物體的位置當成(0,0,0,)後面所有子物體的座標以此為參考
//能夠確認該物體移動時,他所有的子物體也會一起動
//程式在執行的時候可以當成一種綁定位置,使之移動,或是其他編寫腳本時
//所有物體的位置都能維持我們想要的樣子
//若使用transform.position,所有的物體位置會到世界統座標下的位置,各prefab位置會錯亂
void Move()
{
float xOffset;
float zOffset;
float NewxPos;
float NewzPos;
xOffset = xInput * Time.deltaTime * UserMoveSpeed;
zOffset = zInput * Time.deltaTime * UserMoveSpeed;
NewxPos = transform.localPosition.x + xOffset;// 新位置參數 ,相對於父位置的座標
NewzPos = transform.localPosition.y + zOffset;
transform.localPosition = new Vector3
(NewxPos,
transform.localPosition.y,
NewzPos);
}
```
### 第三種 new input system
官方roll a ball教學的寫法,使用新的input system
movementVector.y要放在z軸的原因是,在3D世界,Y軸是垂直的空間,放在Y軸的話會,表現出來會是跳躍,而不是前進。移動效果與第二種使用Input.GetAxis()的寫法相同。
```C#=
public float speed = 0;
private Rigidbody rb;
private float movementX;
private float movementY;
// Start is called before the first frame update
void Start()
{
rb = GetComponent<Rigidbody>();
}
private void OnMove(InputValue movementValue)
{
Vector2 movementVector = movementValue.Get<Vector2>();
movementX = movementVector.x;
movementY = movementVector.y;
}
private void FixedUpdate()
{
Vector3 movement = new Vector3(movementX, 0.0f, movementY);
rb.AddForce(movement * speed);
}
```
### 三之一 一樣是new input system
```C#=
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
public class PlayerMoveControl : MonoBehaviour
{
[SerializeField] Rigidbody rb;
[SerializeField] InputAction movement;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
float horizontalthrow = movement.ReadValue<Vector2>().x;
float Verticalthrow = movement.ReadValue<Vector2>().y;
}
```
### 跳躍
```C#=
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * junpSpeed);
}
```
###### tags: `unity`
{"metaMigratedAt":"2023-06-17T22:31:20.242Z","metaMigratedFrom":"Content","title":"Unity 3D 移動","breaks":true,"contributors":"[{\"id\":\"9be48535-8f15-404d-8fdb-b01990d37456\",\"add\":6075,\"del\":1245}]"}