Unity 3D坦克大战 学习笔记

炮弹发射位置

可以给坦克Prefab增加一个子empty object,位置是坦克炮筒的位置,方向是炮筒方向,这样在发射炮弹脚本处,可以使用这个object的position、rotation。

炮弹碰撞播放粒子特效并销毁炮弹、销毁特效

通过 粒子动画.transform.parent = null 取消粒子与父控件(炮弹)的绑定关系;

Destroy(粒子动画.gameObject, 粒子动画.main.duration) 使得在播放完粒子动画后销毁粒子动画;

Destroy(this.gameObject) 销毁炮弹;

炮弹爆炸播放声音问题

一开始是将播放audio source放在炮弹object中,但是有问题,炮弹碰撞后销毁,声音也随之销毁了。导致无法播放爆炸声音。

正确的做法是将audio source放在爆炸粒子上,随着爆炸粒子销毁。想想也是,因为声音是在爆炸点发出的,如果是跟随炮弹的话,显然声音的位置是不对的。

获取范围内Collider

Collider[] colliders = Physics.OverlapSphere(transform.position, m_ExplosionRadius, m_TankMask);

其中第一个参数是球中心点,第二个参数是半径,第三个参数是要获取的Collider的Layer。

Lerp与SmoothDamp

Lerp是线性的。

private float t1;

t1 += Time.deltaTime;
transform.position = Vector3.Lerp(startPos, target, t1);

t的值是在0-1范围内。

Lerp有时候被使用在平滑场景:

transform.position = Vector3.Lerp(transform.position, target, 0.1f);

个人认为这种使用方法是不对的,理论上position越来越接近目标位置,但是永远无法达到。

SmoothDamp是平滑的。

public float m_DampTime = 0.2f;
private Vector3 m_MoveVelocity;

transform.position = Vector3.SmoothDamp(transform.position, m_DesiredPosition, ref m_MoveVelocity, m_DampTime);

https://www.jianshu.com/p/8a5341c6d5a6

TransformPoint和InverseTransformPoint

将自身坐标转换成世界坐标,和 将世界坐标转换成自身坐标

用法:transform.InverseTransformPoint(Vector3)

Camera.aspect

宽÷高

Camera.orthographicSize

The viewport size of the Camera when set to Orthographic. 当Camera选择正交模式时的视窗大小。

也就是说Camera是Orthographic模式时,可以通过设置orthographicSize以实现镜头拉近、拉远的效果。

注意这个size = 视窗高度的一半

while循环中yield return null;

    private IEnumerator RoundPlaying ()
    {
        // While there is not one tank left...
        while (!OneTankLeft())
        {
            // ... return on the next frame.
            yield return null;
        }
    }

yield return null; 的作用是暂缓一帧,和java中的sleep作用是类似的,sleep是指定暂停多少毫秒,yield return null,是暂停一帧,这一帧过后继续while循环,直到判断条件为false,跳出循环,继续。

外层调用为

    private IEnumerator GameLoop ()
    {
        yield return StartCoroutine (RoundStarting ());

        yield return StartCoroutine (RoundPlaying());

        yield return StartCoroutine (RoundEnding());

        if (m_GameWinner != null)
        {
            Application.LoadLevel (Application.loadedLevel);
        }
        else
        {
            StartCoroutine (GameLoop ());
        }
    }

联合起来就是直到round playing结束后,继续后面的代码。

感觉很有用,可以用在游戏关卡通关控制中。

Transform.Translate与Rigidbody.MovePosition

Transform.Translate是单纯的位移,如果碰撞体遇到障碍物,会有一定的问题,例如抖动、穿透等;如果使用Rigidbody.MovePosition则不会有这些问题。

Awake、OnEnable和Start的执行顺序

在同一个脚本中他们的执行顺序是Awake() —>  Enable() —>  Start()

GameObject的Activity为true,脚本的enable为true时,其先后顺序为:Awake、OnEnable、Start;

GameObject的Activity为true,脚本的enable为false时,只运行Awake;

GameObject的Activity为false时,以上都不调用,OnDisable()被调用;

DustTrail不显示问题

修改粒子属性中”Emiter Velocity”. Change it from Rigidbody to Transform

Slider转圈Progress

正常的Slider的进度是水平的,虽然图片选择成了圆圈,但是如果不设置,还是从左到右。

点击Slider中的Fill,Image Type选择Filled,Fill Method选择Radial 360。

使用InputSystem后,引入UI,导致报错问题

引入UI后,运行报错:

InvalidOperationException: You are trying to read Input using the UnityEngine.Input class, but you have switched active Input handling to Input System package in Player Settings.

解决办法是创建EventSystem,然后再属性中会看到红色叹号,点击下面的Replace with InputSystemUIInputModule。

slider的fill图片变形问题

按照视频里的讲解,给坦克添加蓄力指示箭头。添加完后,发现slider填满后,箭头拉抻变形了,本应是类似Android的9patch,只拉抻一部分。找不到什么原因。

经过不断修改参数尝试,发现修改一些参数可以解决问题,但是不知道所以然。

修改的参数如下:

分别是Sprite和Slider的Fill。

发表评论

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