June 20, 2020: 第一次接触到了Lighting system,光污染似的加了好多hhh 改进了一下操纵火箭的旋转和助推代码,加上加速度和减速度。如此一来操作手感好了一点。Unity建模能力十分差,甚至造不出圆锥,看来还是要学习blender。

private void TrottleInput() { if (Input.GetKey(KeyCode.Space) && ySpeed <= maxSpeed) { // trottle //myRigidBody.AddRelativeForce(Vector3.up); //// v2 ySpeed = transform.InverseTransformDirection(myRigidBody.velocity).y + (acceleration * Time.deltaTime); myRigidBody.AddRelativeForce(Vector3.up * (acceleration * Time.deltaTime)); //// try change velocity directly //Vector3 velocityOnOwnAxis = transform.InverseTransformDirection(myRigidBody.velocity); //ySpeed = velocityOnOwnAxis.y + acceleration * Time.deltaTime; //velocityOnOwnAxis.y = ySpeed; //myRigidBody.velocity = transform.TransformDirection(velocityOnOwnAxis); } else { // update speed ySpeed = transform.InverseTransformDirection(myRigidBody.velocity).y; } }
June 24, 2020: 完成了一个简单的固定路线的飞行游戏。

既然是3d飞行,就要了解飞机的转向:yaw, pitch, row. 下图正好符合左手直角坐标系,也是Unity内默认的坐标系。当飞机需要转向时,只需用左手拟合坐标系,然后握拳方向即是正角度的旋转。


例如如果要用Euler Angle 表述飞机在屏幕左边向左偏航(yaw),在右边向右偏航,在上下側也有俯仰(pitch),同时根据横轴(horizontal axis)的输入大小进行翻滚(row),那么可以这么写代码:
private void ProcessingInput() { float horizontalThrow = CrossPlatformInputManager.GetAxis("Horizontal"); float verticalThrow = CrossPlatformInputManager.GetAxis("Vertical"); Vector3 newPos = transform.localPosition; newPos.x += horizontalThrow * Time.deltaTime * XSpeed; newPos.x = Mathf.Clamp(newPos.x, -XRange, XRange); newPos.y += verticalThrow * Time.deltaTime * YSpeed; newPos.y = Mathf.Clamp(newPos.y, -YRange, YRange); transform.localPosition = newPos; // add a little bit of rotation myRigidBody.angularVelocity = Vector3.zero; Quaternion rotation = Quaternion.Euler(0f, 0f, -maxRollDegree * horizontalThrow); Quaternion tmp = Quaternion.Slerp(transform.localRotation, rotation, Time.deltaTime * rotateDamping); Vector3 tmpEuler = tmp.eulerAngles; tmpEuler.x = (-transform.localPosition.y / pitchMoveRange) * maxPitchDegree; tmpEuler.y = (-transform.localPosition.x / yawMoveRange) * maxYawDegree; tmp.eulerAngles = tmpEuler; transform.localRotation = tmp; }
思路是用向量表示Euler Angle的大小,然后单独构建每一个维度,最后再变成Quaternion
赋值给对象。值得一提的是Unity用Quaternion
做为底层旋转角度的表示好处是不会像Euler Angle一样出现Gimbal Lock
,即一个或两个方向转不动的情况,不便之处就是ijk
的值有点难直观理解。幸好Unity提供了对Euler Angle的直接转换。
接下来打算用做学的知识做一个空战游戏,结合blender建模做个3d自由视角的low-poly娱乐向空战似乎也不错。真正的空战游戏应该给玩家三个维度(pitch, yaw, row)的操作自由度,再加上油门的大小。当然很多空战游戏其实是简化的。立flag早日写出Controller
和调校好镜头跟随。先下载下来别人优秀的源码研究一下先。

此外,Unity其实有不少地方暗示了c#的一个特性:reflection。不同于相当于协程的Invoke()
,Gameobject.SendMessage()
其实是反射机制,它在每一帧调用对象内的所有MonoBehavior
。我的猜测是由于c#存在反射机制,它可以方便地通过GetType()
之类的函数调用对象的方法、特性等。c#真的是很完美的语言了。