最近公司在开发一款儿童打飞机游戏. 策划跟我说能在子弹上加上一些轨迹就好了. 比如 旋转 左右移动呀.然后它就很愉快的跑去截其他游戏的图啦。。。
我看见图的时候,
解决方案:
1. 使用牛逼的算法,实现子弹轨迹的移动(第一种应该是正确的解决方案)
2. 发射子弹次数 + 前后移动 + 左右移动 + 围绕某点旋转 + 自身旋转 = 子弹轨迹. 采用组合方式实现
目前采用第二种方式:
我们来看下子弹,两个齿轮会绕着中心旋转, 并且向下移动. ( 围绕某点旋转 + 自身旋转 + 前后移动 = 实现效果)
子弹的GameObject节点层次关系: (此结构和任意组合,但不要把全部功能放在同一个节点上. =。=这样理不清还会受到干扰)
前后移动节点(看两个齿轮中心点向下移动)
左右移动节点(无这个功能,无需开启脚本)
围绕父节点旋转节点(两个此轮围绕中心旋转)
自身旋转节点(比如齿轮它自身会旋转)
下面的子弹实现方式: 自身旋转 + 左右移动 + 上下移动 = 实现效果
============================================================================================================================
代码区域:
左右移动脚本:
using UnityEngine; using System.Collections; namespace Bullet { /// <summary> /// 子弹横向左右移动 /// </summary> 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 { /// <summary> /// 子弹旋转 /// </summary> 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; } } } } /// <summary> /// 旋转的方向 /// </summary> public enum RotationDirection { Left, None, Right } }
子弹前后移动:
using UnityEngine; using System.Collections; using BearGame; namespace Bullet { /// <summary> /// 子弹前后移动 /// </summary> public class BulletVertical : MonoBehaviour { public float speed = 0; public BulletDirectionEnum direction; private Vector3 dir; public delegate void BulletOutScreen(GameObject gameObject); /// <summary> /// 子弹越屏之后,触发的事件,用于销毁子弹 /// </summary> /// <param name="gameObject"></param> 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); //调用子弹出屏幕事件
}
} } /// <summary> /// 子弹移动的方向 /// </summary> public enum BulletDirectionEnum { Up, Bottom, Left, Right, None } }
子弹轨迹总体脚本控制:
using UnityEngine; using System.Collections; using BearGame; namespace Bullet { public class BulletMode : MonoBehaviour { /// <summary> /// 子弹预设 /// </summary> private GameObject bullet; /// <summary> /// 子弹的名称 /// </summary> private string bulletName; /// <summary> /// 子弹爆炸特效 /// </summary> public Transform bulletEffect; /// <summary> /// 向左右移动 /// </summary> public BulletHorizontal bulletHorizontal; /// <summary> /// 向前后移动 /// </summary> public BulletVertical bulletForce; /// <summary> /// 围绕某一个点旋转 /// </summary> public BulletRotate bulletRotateARound; /// <summary> /// 围绕自身旋转 /// </summary> 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; } } }