最近公司在开发一款儿童打飞机游戏. 策划跟我说能在子弹上加上一些轨迹就好了. 比如 旋转 左右移动呀.然后它就很愉快的跑去截其他游戏的图啦。。。
我看见图的时候,
解决方案:
1. 使用牛逼的算法,实现子弹轨迹的移动(第一种应该是正确的解决方案)
2. 发射子弹次数 + 前后移动 + 左右移动 + 围绕某点旋转 + 自身旋转 = 子弹轨迹. 采用组合方式实现
目前采用第二种方式:
我们来看下子弹,两个齿轮会绕着中心旋转, 并且向下移动. ( 围绕某点旋转 + 自身旋转 + 前后移动 = 实现效果)
子弹的GameObject节点层次关系: (此结构和任意组合,但不要把全部功能放在同一个节点上. =。=这样理不清还会受到干扰)
前后移动节点(看两个齿轮中心点向下移动)
左右移动节点(无这个功能,无需开启脚本)
围绕父节点旋转节点(两个此轮围绕中心旋转)
自身旋转节点(比如齿轮它自身会旋转)
下面的子弹实现方式: 自身旋转 + 左右移动 + 上下移动 = 实现效果
============================================================================================================================
代码区域:
左右移动脚本:
using UnityEngine;using System.Collections;namespace Bullet { ////// 子弹横向左右移动 /// public class BulletHorizontal : MonoBehaviour { public bool isLeft; //是否向左移动 public float moveLocation; //移动的位置 public float speed; //移动速度 private Vector3 leftPosition; //左边的目标点 private Vector3 rightPosition; //右边的目标点 void Awake() { leftPosition = new Vector3(transform.localPosition.x - moveLocation, transform.localPosition.y, transform.localPosition.z); rightPosition = new Vector3(transform.localPosition.x + moveLocation, transform.localPosition.y, transform.localPosition.z); } void Update() { if (isLeft) { transform.localPosition += (Vector3.right * speed * Time.deltaTime); //transform.Translate(Vector3.right * speed * Time.deltaTime); if (transform.localPosition.x >= rightPosition.x) { isLeft = !isLeft; } } else { transform.localPosition += (Vector3.left * speed * Time.deltaTime); //transform.Translate(Vector3.left * speed * Time.deltaTime); if (transform.localPosition.x <= leftPosition.x) { isLeft = !isLeft; } } } }}
子弹旋转脚本:
using UnityEngine;using System.Collections;using BearGame;namespace Bullet { ////// 子弹旋转 /// public class BulletRotate : MonoBehaviour { public RotationDirection rotationDirection; public float speed; public Transform rotateNode; public void Update() { if (rotateNode != null) { //围绕某一节点旋转 switch (rotationDirection) { case RotationDirection.Left: this.transform.RotateAround(rotateNode.transform.position, Vector3.forward, speed); break; case RotationDirection.Right: this.transform.RotateAround(rotateNode.transform.position, Vector3.forward, -(speed)); break; } } else { //自身旋转 switch (rotationDirection) { case RotationDirection.Left: this.transform.Rotate(Vector3.forward, speed); break; case RotationDirection.Right: this.transform.Rotate(Vector3.forward, -(speed)); break; } } } } ////// 旋转的方向 /// public enum RotationDirection { Left, None, Right }}
子弹前后移动:
using UnityEngine;using System.Collections;using BearGame;namespace Bullet{ ////// 子弹前后移动 /// public class BulletVertical : MonoBehaviour { public float speed = 0; public BulletDirectionEnum direction; private Vector3 dir; public delegate void BulletOutScreen(GameObject gameObject); ////// 子弹越屏之后,触发的事件,用于销毁子弹 /// /// public static event BulletOutScreen OnBulletDestroy; void Start() { switch (direction) { case BulletDirectionEnum.Up: dir = Vector3.up; break; case BulletDirectionEnum.Bottom: dir = -Vector3.up; break; case BulletDirectionEnum.Left: dir = Vector3.left; break; case BulletDirectionEnum.Right: dir = Vector3.right; break; } } void Update() {
transform.Translate(dir * speed * Time.deltaTime); if (transform.localPosition.y > Screen.height) { transform.gameObject.SetActive(false); //调用子弹出屏幕事件
}
} } ////// 子弹移动的方向 /// public enum BulletDirectionEnum { Up, Bottom, Left, Right, None }}
子弹轨迹总体脚本控制:
using UnityEngine;using System.Collections;using BearGame;namespace Bullet { public class BulletMode : MonoBehaviour { ////// 子弹预设 /// private GameObject bullet; ////// 子弹的名称 /// private string bulletName; ////// 子弹爆炸特效 /// public Transform bulletEffect; ////// 向左右移动 /// public BulletHorizontal bulletHorizontal; ////// 向前后移动 /// public BulletVertical bulletForce; ////// 围绕某一个点旋转 /// public BulletRotate bulletRotateARound; ////// 围绕自身旋转 /// public BulletRotate bulletRotateOneself; #region 属性 public GameObject Bullet { get { if (bullet == null) { bullet = this.gameObject; } return bullet; } set { bullet = value; } } public string BulletName { get { if (string.IsNullOrEmpty(bulletName)) { bulletName = this.gameObject.name; } return bulletName; } set { bulletName = value; } } #endregion public void TrunOFFALLScript() { if (bulletRotateOneself != null) bulletRotateOneself.enabled = false; if (bulletRotateARound != null) bulletRotateARound.enabled = false; if (bulletForce != null) bulletForce.enabled = false; if (bulletHorizontal != null) bulletHorizontal.enabled = false; } public void TrunOpenALLScript() { if (bulletRotateOneself != null) bulletRotateOneself.enabled = true; if (bulletRotateARound != null) bulletRotateARound.enabled = true; if (bulletForce != null) bulletForce.enabled = true; if (bulletHorizontal != null) bulletHorizontal.enabled = true; } }}