[Unity自学] DevLog 1: Week 3&4, June 2020

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

Rocket Boost Project Following GameDev.tv Tutorial
   private void TrottleInput()
    {
        if (Input.GetKey(KeyCode.Space) &amp;&amp; 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: 完成了一个简单的固定路线的飞行游戏。

Argon Assault Project Following Tutorial

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

Aircraft Principal Axes From Wiki and My Screenshot

例如如果要用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#真的是很完美的语言了。

点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注