最近公司在开发一款儿童打飞机游戏. 策划跟我说能在子弹上加上一些轨迹就好了. 比如 旋转 左右移动呀.然后它就很愉快的跑去截其他游戏的图啦。。。
我看见图的时候,
解决方案:
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;
} } }