Unity Note - Project09 Movement
coconutnut

最终想要做的移动方式:

  • 点击地面导航
  • 拖拽旋转
  • 缩放平移
  • 点击画导航

交互方式参考:

https://sketchfab.com/3d-models/richards-art-gallery-audio-tour-0e3e19faa6474fd5974e6a7ed1b221d8

搭建

点击移动

参考Project02,AI导航+NavMeshAgent

1
2
3
4
5
6
7
if(Input.GetMouseButtonDown(0)){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, Mathf.Infinity)){
agent.SetDestination(hit.point);
}
}

判断落点,只有是地面才移动(地面打Tag)

1
2
3
4
5
6
7
8
9
if(Input.GetMouseButtonDown(0)){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, Mathf.Infinity)){
if(hit.transform.tag == "Floor"){
agent.SetDestination(hit.point);
}
}
}

点击特效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// click to navigate
if(Input.GetMouseButtonDown(0)){
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, Mathf.Infinity)){
// move when hit floor
if(hit.transform.tag == "Floor"){
agent.SetDestination(hit.point);

// click effect
GameObject clickEffectObject = Instantiate(clickEffect);
clickEffectObject.transform.position = hit.point;
Destroy(clickEffectObject, 0.5f);
}
}
}

拖拽旋转视角

1
2
3
4
5
6
7
8
9
10
11
// get mouse position
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

// rotate camera up and down
cameraRotation -= mouseY;
cameraRotation = Mathf.Clamp(cameraRotation, -30f, 30f);
cameraTransform.localRotation = Quaternion.Euler(cameraRotation, 0f, 0f);

// rotate player left and right
transform.Rotate(Vector3.up * (mouseX));

此时长按拖拽和点击寻路会混,加一个mouseDownCount计数

缩放前后移动

1
2
3
4
5
6
// stop navigation
agent.ResetPath();

// scroll to move forward and backward
Vector3 move = transform.forward * Input.GetAxis("Mouse ScrollWheel") * scrollSensitivity;
agent.Move(move * Time.deltaTime);

!这里一定要先停止寻路,否则会乱抖

最终

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
[SerializeField, Range(0f,100f)]
private float scrollSensitivity = 10f;

[SerializeField, Range(0f,500f)]
private float mouseSensitivity = 200f;

[SerializeField]
private Transform cameraTransform = null;

private float cameraRotation = 0f;
private int mouseDownCount = 0;

UnityEngine.AI.NavMeshAgent agent;

GameObject clickEffect;

void Start()
{
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();

clickEffect = Resources.Load<GameObject>("Prefabs/ClickEffect");
}

void Update()
{
if(Input.GetMouseButtonUp(0)){
// if is click
if(mouseDownCount < 2){
// click to navigate
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, Mathf.Infinity)){
// move when hit floor
if(hit.transform.tag == "Floor"){
agent.SetDestination(hit.point);

// click effect
GameObject clickEffectObject = Instantiate(clickEffect);
clickEffectObject.transform.position = hit.point;
Destroy(clickEffectObject, 1);
}
}
}
mouseDownCount = 0;
}else if(Input.GetAxis("Mouse ScrollWheel") != 0){
// stop navigation
agent.ResetPath();

// scroll to move forward and backward
Vector3 move = transform.forward * Input.GetAxis("Mouse ScrollWheel") * scrollSensitivity;
agent.Move(move * Time.deltaTime);
}else if(Input.GetMouseButton(0)){
// stop navigation
agent.ResetPath();

// get mouse position
float mouseX = Input.GetAxis("Mouse X") * mouseSensitivity * Time.deltaTime;
float mouseY = Input.GetAxis("Mouse Y") * mouseSensitivity * Time.deltaTime;

// rotate camera up and down
cameraRotation -= mouseY;
cameraRotation = Mathf.Clamp(cameraRotation, -30f, 30f);
cameraTransform.localRotation = Quaternion.Euler(cameraRotation, 0f, 0f);

// rotate player left and right
transform.Rotate(Vector3.up * (mouseX));

mouseDownCount++;
}
}
}

点击寻路

滚动前后平移

拖拽旋转视角

且寻路过程中,滚动或拖拽均打断寻路