遨游unity

想法

如题,记录一下遨游unity时碰到的小问题,往往是网上难以找到资料的,或是资料容易产生误导的。

摄像机设置透视或正交

开发一个2d小游戏时,碰撞盒计算没有问题,但是在游戏界面总有非预期的重叠效果,像是碰撞盒错位了。
一番研究发现是摄像机的问题:2d游戏应当使用正交。
在物体有z轴的情况下,摄像机是透视的,就会产生这种错位现象。
反过来说,在2d游戏中采用摄像机透视和z轴,就可以做出类似《奥日》的背景前景的效果,营造纵深。

鼠标点击位置

如何判断一个鼠标是否点到某个物体呢?
UI上的还比较简单,如果是3d的呢。
从摄像机打一条射线通过鼠标点击的地方,碰撞到物体,就知道玩家点的哪个东西了

1
2
3
4
5
6
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
GameObject box = hit.collider.gameObject; //获得选中物体
}

改变TextMeshPro中的文字

经常用到TextMeshPro来做UI,这是个需要导入的库,有些组件也和原生的有些规范差异。
这样修改文字

1
2
3
using TMPro; //最上方导入

box.GetComponent<TMP_Text>().text = word[card_type];

unity语法提示

默认打开vs时是没有unity语法提示的
打开方式:编辑->首选项->外部工具->外部脚本编辑器
再选中一个,重启下vs。

动画控制器

其中的离开时间的数值是动画的百分比长度,而不是秒数

碰撞箱相关

OnCollision:

1.双方必须要有Collider

2.其中一方必须要有刚体

3.有刚体的一方不能勾选Is Trigger

PS:此情况下会有刚体的物体碰撞效果,而且无法在没有刚体物理碰撞效果下触发该函数

OnTrigger:

1.双方必须要有Collider

2.其中一方勾选Is Trigger

3.其中一方必须要有刚体

PS:在带刚体的物体下的Colloder中勾选Is Trigger后刚体的物理碰撞效果会失效

常用camera脚本

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
using UnityEngine;
using UnityEngine.EventSystems;

public enum CamViewMode
{
FREE,//自由视角
TOP,//俯视角
LIMIT//固定视角
}
public class CameraControlScript : MonoBehaviour
{
//相机物体
private Transform camTrans;

/// <summary>
/// 是否是第一次点击
/// </summary>
private bool _isFirstClick = true;

/// <summary>
/// 相机视角模式
/// </summary>
public CamViewMode viewMode = CamViewMode.FREE;

[SerializeField]
private Vector3 _resetTrans;//相机重置位置
[SerializeField]
private Vector3 _resetAngles;//相机重置角度

[Header("键盘移动速度")]
public float m_speed = 3f;
[Header("鼠标中键移动速度")]
public float m_mSpeed = 0.5f;
[Header("旋转速度")]
public float m_rSpeed = 5f;
[Header("缩放速度")]
public float m_sSpeed = 5f;
[Header("最大缩放距离")]
public float m_maxDistance = 10f;
[Header("中键移动的缓动值")]
public float moveSmoothing = 0.2f;

private float m_deltX = 0f;//计算右键旋转
private float m_deltY = 0f;//计算右键旋转

void Start()
{
camTrans = transform;
}
void Update()
{
//在UI上时不执行
//if (EventSystem.current.IsPointerOverGameObject()) return;

if (viewMode != CamViewMode.LIMIT)
{
//有的没加缓动效果
CameraKeyMove();
CameraMiddleMove();
CameraRotate();
CameraScale();
}

//不同视角
CameraMode();

//相机复位
if (Input.GetKeyUp(KeyCode.Space))
{
CameraReset();
}


}
private void CameraMode()
{
switch (viewMode)
{
case CamViewMode.TOP:
camTrans.localRotation = Quaternion.Euler(90, camTrans.localRotation.eulerAngles.y, camTrans.localRotation.eulerAngles.z);
break;
default:
break;
}
}
void CameraScale()
{
//鼠标滚轮场景缩放;
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
float m_distance = Input.GetAxis("Mouse ScrollWheel") * m_sSpeed;
Vector3 newPos = camTrans.localPosition + camTrans.forward * m_distance;
// Debug.Log(newPos.magnitude);
if (newPos.magnitude >= m_maxDistance) return;
camTrans.localPosition = newPos;
}
}
void CameraRotate()
{
//鼠标右键点下控制相机旋转;
if (Input.GetMouseButton(1))
{
if (!_isFirstClick)
{
m_deltX += Input.GetAxis("Mouse X") * m_rSpeed;
m_deltY -= Input.GetAxis("Mouse Y") * m_rSpeed;
}
else//第一次点击时规划角度
{
_isFirstClick = false;
m_deltX = _resetAngles.y;
m_deltY = _resetAngles.x;
}

m_deltX = ClampAngle(m_deltX, -360, 360);
m_deltY = ClampAngle(m_deltY, -70, 70);

camTrans.localRotation = Quaternion.Euler(m_deltY, m_deltX, 0);
}

}
void CameraKeyMove()
{
//键盘移动
if (Input.GetKey(KeyCode.W) || Input.GetKey(KeyCode.UpArrow))
{
camTrans.Translate(Vector3.forward * Time.deltaTime * m_speed);
}
if (Input.GetKey(KeyCode.S) || Input.GetKey(KeyCode.DownArrow))
{
camTrans.Translate(Vector3.back * Time.deltaTime * m_speed);
}
if (Input.GetKey(KeyCode.A) || Input.GetKey(KeyCode.LeftArrow))
{
camTrans.Translate(Vector3.left * Time.deltaTime * m_speed);
}
if (Input.GetKey(KeyCode.D) || Input.GetKey(KeyCode.RightArrow))
{
camTrans.Translate(Vector3.right * Time.deltaTime * m_speed);
}
}
void CameraMiddleMove()
{
//点击鼠标中键控制移动;
if (Input.GetMouseButton(2))
{
float dx = Input.GetAxis("Mouse X");
float dy = Input.GetAxis("Mouse Y");
Vector3 yz = camTrans.forward + camTrans.up;
yz.y = 0;
Vector3 TargetLookAt = camTrans.position;
TargetLookAt -= (yz * dy + transform.right * dx) * m_mSpeed;
camTrans.position = Vector3.Lerp(camTrans.position, TargetLookAt, moveSmoothing);
}
}
public void CameraReset()
{
//相机位置和角度重置,需要自己设一个初始的位置和角度
camTrans.localPosition = _resetTrans;
camTrans.localRotation = Quaternion.Euler(_resetAngles);
}
//规划角度;
float ClampAngle(float angle, float minAngle, float maxAgnle)
{
if (angle <= -360)
angle += 360;
if (angle >= 360)
angle -= 360;

return Mathf.Clamp(angle, minAngle, maxAgnle);
}

}


中心点不变地旋转摄像头

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraControlScript2 : MonoBehaviour
{
// Start is called before the first frame update

[Header("摄像头对准中心")]
public Vector3 m_Point = new Vector3();
[Header("旋转速度")]
public float m_rSpeed = 3f;
[Header("旋转的缓动值")]
public float rotateSmoothing = 0.05f;
[Header("缩放最小距离")]
public float m_minDistance = 1.0f;
[Header("缩放最大距离")]
public float m_maxDistance = 100.0f;
[Header("缩放速度")]
public float m_sSpeed = 5f;

private Transform camTrans;
private bool _isFirstClick = true;
private float m_deltX = 0f;//计算右键旋转
private float m_deltY = 0f;//计算右键旋转
private float m_distanceToPoint;
private float m_rotateSpeedX;
private float m_rotateSpeedY;

void Start()
{
camTrans = transform;
m_distanceToPoint = Vector3.Distance(m_Point, camTrans.localPosition);
camTrans.forward = m_Point - camTrans.localPosition;
GetComponent<Camera>().depthTextureMode = DepthTextureMode.Depth;

}

// Update is called once per frame
void Update()
{
CameraScale();
CameraRotate();
}

void CameraScale()
{
//鼠标滚轮场景缩放;
if (Input.GetAxis("Mouse ScrollWheel") != 0)
{
float m_distance = Input.GetAxis("Mouse ScrollWheel") * m_sSpeed;
Vector3 newPos = camTrans.localPosition + camTrans.forward * m_distance;
if (Vector3.Distance(m_Point, newPos) > m_maxDistance || Vector3.Distance(m_Point, newPos) < m_minDistance)
{
return;
}
camTrans.localPosition = newPos;
m_distanceToPoint = Vector3.Distance(m_Point, camTrans.localPosition);

}
}

void CameraRotate()
{
//鼠标右键点下控制相机旋转;
if (Input.GetMouseButton(1))
{
if (!_isFirstClick)
{
m_deltX = Input.GetAxis("Mouse X") * m_rSpeed;
m_deltY = -Input.GetAxis("Mouse Y") * m_rSpeed;
}
else//第一次点击时规划角度
{
_isFirstClick = false;
m_deltX = 0;
m_deltY = 0;
}

m_rotateSpeedX += m_deltX / m_distanceToPoint;
m_rotateSpeedY += m_deltY / m_distanceToPoint;
}
m_rotateSpeedX *= (1 - rotateSmoothing);
m_rotateSpeedY *= (1 - rotateSmoothing);

camTrans.RotateAround(m_Point, camTrans.up, m_rotateSpeedX);
camTrans.RotateAround(m_Point, camTrans.right, m_rotateSpeedY);
// camTrans.forward = m_Point - camTrans.localPosition;
}

}

与场景中物体交互

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
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraMouseScript : MonoBehaviour
{
// Start is called before the first frame update

private Vector3 startHitPos;
private Vector3 startHitCubePos;
private Vector3 endHitPos;
private GameObject endHitCube;

private bool isHitting;

void Start()
{
isHitting = false;
}

// Update is called once per frame
void Update()
{
MouseRayCast();
}

void MouseRayCast()
{
if (Input.GetMouseButtonDown(0) && !isHitting)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.gameObject)
{
startHitPos = new Vector3(hit.point.x, hit.point.y, hit.point.z);
GameObject cube = hit.collider.gameObject;
startHitCubePos = new Vector3(cube.transform.position.x, cube.transform.position.y, cube.transform.position.z);
isHitting = true;
}
}
}
if (Input.GetMouseButtonUp(0) && isHitting)
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 1000))
{
if (hit.collider.gameObject)
{
endHitPos = new Vector3(hit.point.x, hit.point.y, hit.point.z);
endHitCube = hit.collider.gameObject;
endHitCube.GetComponent<SingleCubeScript>().CenterCube.GetComponent<CubeScript>()
.GetObject(startHitPos, startHitCubePos, endHitPos, endHitCube.transform.position);
isHitting = false;
}

}
}
}
}

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2020-2022 d1gg12
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信