Project V0.1.1 Record - UI,Event
coconutnut

Canvas大小

https://www.youtube.com/watch?v=OKK69bmjmJE&ab_channel=Creagines

Canvas Scaler-> 缩放模式 -> 屏幕大小缩放

解决了上次文字飞掉的问题

可以下一步啦

点击按钮

https://www.cnblogs.com/Peng18233754457/p/7792442.html

一开始事件用的是Button的onClick()

发现Event System更好用

  • Button上鼠标单击()里+ (其它事件可以添加组件触发)
  • EventTest.cs中 public void A()

Button这样就可以了

3D物体要使用,还要先给Main Camera加一个Physics Raycaster组件

点击寻路

Player监听点击实现,更改寻路

https://www.youtube.com/watch?v=wlo-ZvV3ovg&ab_channel=JasonWeimann

参考↑通过Action实现,避免到处reference

寻路转向

寻路完成后转向board

设置了一个isNavigating变量,记录状态

到达后用DOTWeen转向

寻路打断

每次有输入时,打断寻路,同时将设置成false

一个小问题是,第一次点击board时将isNavigating设成true,但同时Input.GetMouseButtonUp(0)也会为true,所以额外用了一个firstClick判断是否为第一次点击

最后相关代码:

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
private bool isNavigating = false;
private bool firstClick = true;
private Vector3 turnPosition;

void Update()
{
if(Input.GetMouseButtonUp(0)){
if(isNavigating){
if(firstClick){
firstClick = false;
}else{
isNavigating = false;
}
}else{
firstClick = true;
// 这里可能有点点问题,isNavigating设成false之后,要下一次Update才能检测到,但是Update调得很快,基本感觉不到,所以暂时就这样写了,看着舒服些。但MARK一下,以后如果有问题,再把这里拆出去单独判断。
}

// ...

}else if(Input.GetMouseButton(0)){
isNavigating = false;

// ...

}else if(Input.GetAxis("Mouse ScrollWheel")!=0 || Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0){
isNavigating = false;

// ...
}
}
}

private void SetNewDestination(Vector3 destination, Vector3 boardPosition) {
// set new destination
agent.SetDestination(destination);

// set turn destination
turnPosition = boardPosition;
isNavigating = true;
}

02.19 update

后续做导游时发现,点击UI寻路按钮时,事件发生的顺序是:

  • GetMouseButton
  • Set Destination
  • GetMouseButtonUp

而再次GetMouseButton和GetMouseButtonUp都需要打断,用之前的方法很混乱

于是改成三种状态,只能按顺序切换

  1. GuideStatus.Static 默认状态

  2. GuideStatus.Ready 设置寻路后,Static->Ready

  3. GuideStatus.On

    • Ready状态获取到一次GetMouseButtonUp,变成On
    • On状态时,GetMouseButton或GetMouseButtonUp均会打断寻路,变成Static
    • On状态到达目的地后,变成Static

测试目前没什么问题

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
private Vector3 turnPosition;
private GuideStatus currentGuideStatus = GuideStatus.Static;
private enum GuideStatus
{
Static,
Ready,
On
}

void Update()
{
if(Input.GetMouseButtonUp(0)){
// if is click
if(mouseDownCount < 2){
if(currentGuideStatus == GuideStatus.Ready){
currentGuideStatus = GuideStatus.On;
}else if(currentGuideStatus == GuideStatus.On){
currentGuideStatus = GuideStatus.Static;
Debug.Log("[guide] disrupted by GetMouseButtonUp-Click");
}

// ...
mouseDownCount = 0;

}else if(Input.GetMouseButton(0)){
if(currentGuideStatus==GuideStatus.On){
currentGuideStatus = GuideStatus.Static;
Debug.Log("[guide] disrupted by GetMouseButton");
}

// ...

mouseDownCount++;

}else if(Input.GetAxis("Mouse ScrollWheel")!=0 || Input.GetAxis("Horizontal")!=0 || Input.GetAxis("Vertical")!=0){
if(currentGuideStatus==GuideStatus.On){
currentGuideStatus = GuideStatus.Static;
Debug.Log("[guide] disrupted by Movement");
}

// ...

}else{
if(currentGuideStatus==GuideStatus.On && agent.remainingDistance==0){
Debug.Log("[guide] look at "+turnPosition);
transform.DOLookAt(turnPosition,turnDuration,AxisConstraint.Y);
currentGuideStatus = GuideStatus.Static;
Debug.Log("[guide] end");
}
}
}

private void SetNewDestination(Vector3 destination, Vector3 destination2) {
Debug.Log("[guide] start");
currentGuideStatus = GuideStatus.Ready;

// set new destination
agent.SetDestination(destination);

// set turn destination
turnPosition = destination2;
}

UI遮盖Raycast

加完导航寻路的UI之后,发现raycast仍可以穿透UI,同时点击寻路

看到一种解决是用EventSystem.current.IsPointerOverGameObject()

但是Canvas是全屏大小,点击哪里都是true

Canvas Group也没有用

https://stackoverflow.com/questions/52654002/unity-not-ignoring-button-click-in-ignore-raycast-layer

最后参考这个

https://gameinstitute.qq.com/community/detail/129017

给所有的Button加了tag来判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private bool IsPointerOverUIObject(){
// get mouse position
PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);

// get all raycast result
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(eventDataCurrentPosition, results);

// check UI tag
foreach(RaycastResult r in results){
if(r.gameObject.tag == "UI"){
return true;
}
}
return false;
}

脚本执行顺序问题

做了导航栏之后,发现初始化顺序有点问题

导航栏要使用Board上的数字和名字,有时会为默认值

选中任意一个script,调整Inspector->Execution Order,解决