直接贴代码了
using UnityEngine; using System; using System.Collections; using System; using DataTable; public class ObjDropItem : ObjBase { //类型 public override OBJ.TYPE GetObjType() { return OBJ.TYPE.DROPITEM; } public const float MAXSPEED = 20; enum State { Load, Delay, Droping, StayOnGround, Pickup, FlyToPlayer, Destory, } //外置表现参数 [Tooltip("飞到玩家身上那个高度位置")] public float PlayerOffset = 1.4f; [Tooltip("开启安全模式(TotalLifeTime秒后强制删除)")] public bool SafeMode = true; [Tooltip("存在最长时间(秒)")] public float TotalLifeTime = 300; [Tooltip("掉落都地上高度")] public float DropHight = 0.5f; [Tooltip("掉落都地上用时")] public float DropTime = 0.3f; [Tooltip("多长时间后出现")] public float DelayTime = 0.5f; [Tooltip("自动拾取距离")] public float AutoPickUpDistance = 2.0f; [Tooltip("在地上呆的时间")] public float DropOverDelayTime = 0.2f; [Tooltip("物品速度")] [Range(0, 15)] public float MoveSpeed = 10.0f; [Tooltip("距离多少是已经飞到玩家身上")] public float MaxDistance = 0.2f; [Tooltip("控制点离我的直线距离")] public float ControlPointOffsetDistance = 3.0f; [Tooltip("控制点高度")] public float ControlPointOffsetHeight = 2.0f; [Tooltip("控制点速度,必须要大于物品速度")] [Range(15, 25)] public float ControlPointSpeed = 15.0f; [Tooltip("速度增量")][Range(0,2)] public float AccSpeed = 0.1f; DropItemController mController; //状态 private State mState = State.Load; //生命时间 private DateTime mLifeTime = DateTime.Now; //是否可以自动拾取 private bool mCanAutoPickup = false; //拥有者id private bool mOwnerIsMe; //拥有者拾取保护时间 private DateTime mOwnerPickUpProtectionTime; //飞往目标点(也就是服务端实际坐标) private Vector3 mTargetPos; //控制点 private Vector3 mControlPoint; //控制点 private bool mControlPointReached; //控制点速度 private float mControlPointMoveSpeed; //移动速度 private float mMoveSpeed; public virtual void Awake() { #if !UNITY_EDITOR try { #endif base.Awake(); #if !UNITY_EDITOR } catch (Exception ex) { Logger.Error(ex.ToString()); } #endif } //重置 public override void Reset() { base.Reset(); mState = State.Load; mLifeTime = DateTime.Now.AddSeconds(TotalLifeTime); mCanAutoPickup = false; mOwnerPickUpProtectionTime = DateTime.Now; } //初始化 public override bool Init(InitBaseData initData, Action callback = null) { base.Init(initData); Reset(); InitDropItemData data = initData as InitDropItemData; mOwnerIsMe = false; mCanAutoPickup = false; var player = ObjManager.Instance.MyPlayer; if (player) { if (player.GetObjId() == data.Owner) { mOwnerIsMe = true; mCanAutoPickup = true; } } mOwnerPickUpProtectionTime = DateTime.Now.AddSeconds(data.RemianSeconds); mLifeTime = DateTime.Now.AddSeconds(TotalLifeTime); float height = GameLogic.Instance.Scene.GetTerrainHeight(data.TargetPos) + 0.1f; mTargetPos = new Vector3(data.TargetPos.x, height, data.TargetPos.y); LoadRes(() => { if (true != data.PlayDrop) {//需要播放掉落动画 Position = mTargetPos; mState = State.StayOnGround; } else {//不需要播放掉落动画 this.StartCoroutine(Delay()); mState = State.Delay; } if (null != callback) callback(); mController = mModel.GetComponent<DropItemController>(); if (null != mController) { mController.ShowModel(true); mController.ShowEffect(false); } }); return true; } //是否可以被拾取 public bool CanPickup() { if (State.StayOnGround != mState && State.Pickup != mState) {//只有停留在地上这种状态才能被拾取 return false; } if (DateTime.Now<mOwnerPickUpProtectionTime) {//当前时间在拥有者保护时间内 return mOwnerIsMe; } else {//过了拥有者保护时间谁都可以拾取 return true; } } void Update () { #if !UNITY_EDITOR try { #endif if (true==SafeMode) { if (DateTime.Now > mLifeTime) {//为了安全,怎么也该消失了 Logger.Warn("Drop item[{0}] stays too long", mObjId); mState = State.Destory; if (ObjManager.Instance.FindObjById(mObjId).Equals(this)) { ObjManager.Instance.RemoveObj(mObjId); } else { base.Destroy(); } return; } } var player = ObjManager.Instance.MyPlayer; if (null == player) return; if (State.StayOnGround == mState) {//停在地上 if (CanPickup() && mCanAutoPickup) {//可以自动拾取 float distance = Vector2.Distance(player.Position.xz(), Position.xz()); if (distance <= AutoPickUpDistance) {//距离足够近 var control = UIManager.Instance.GetController(UIConfig.SettingUI); if ((bool)control.CallFromOtherClass("CanPiackUpItem", new object[] { mDataId })) {//是否可拾取这种类型物品 Pickup(); } mCanAutoPickup = false; } } } else if (State.FlyToPlayer == mState) {//我拾取成功,物品正在往我身上飞 var delta = Time.deltaTime; var temp = player.Position; temp.y += PlayerOffset; //控制点朝着主角飞 if(!mControlPointReached) { float distance = Vector2.Distance(temp, mControlPoint); if (distance <= MaxDistance) {//当前已经飞到了 mControlPointReached = true; } else { mControlPointMoveSpeed += delta * AccSpeed; mControlPointMoveSpeed = Math.Min(mControlPointMoveSpeed, MAXSPEED); float moveDis = mControlPointMoveSpeed * delta; if (moveDis >= distance) {//这一步就飞到了 mControlPointReached = true; } else {//继续移动 var controlPointDir = (temp - mControlPoint).normalized; mControlPoint += controlPointDir * moveDis; } } } if (mControlPointReached) { mControlPoint = temp; } {//自己朝着控制点飞 float dis = Vector3.Distance(mControlPoint, Position); if (dis <= MaxDistance && mControlPointReached) { mState = State.Destory; Destroy(); return; } else { mMoveSpeed += AccSpeed * delta; mMoveSpeed = Math.Min(mMoveSpeed, MAXSPEED); float moveDis = mMoveSpeed * delta; if(moveDis>=dis) { Position = mControlPoint; if (mControlPointReached) { mState = State.Destory; Destroy(); return; } } else { var dir = (mControlPoint - Position).normalized; Position = Position + dir * moveDis; } } } } #if !UNITY_EDITOR } catch (Exception ex) { Logger.Error(ex.ToString()); } #endif } //拾取 public void Pickup() { if(CanPickup()) { NetManager.Instance.SendPickUpItemRequest(GetObjId()); mState = State.Pickup; } mCanAutoPickup = false; } protected virtual void LoadRes(Action callback = null) { string prafabPath = ""; var table = Table.GetItemBase(mDataId); if(null==table) { Logger.Error("NULL==Table.GetItemBase({0})", mDataId); } else { var tableDrop = Table.GetDropModel(table.DropModel); if (null == tableDrop) { Logger.Error("NULL==Table.GetDropModel({0})", table.DropModel); } else { prafabPath = tableDrop.ModelPath; } } if ("" == prafabPath) { Logger.Error("null==prafabPath)"); return; } UniqueResourceId = GetNextUniqueResourceId(); var resId = UniqueResourceId; ComplexObjectPool.NewObject(prafabPath, model => { if (resId != UniqueResourceId) { return; } SetModel(model); //SetScale((float)tableDrop.aScale); 这个缩放放到prefab上 if (null != callback) { callback(); } }); } void PlayDropSound() { var table = Table.GetItemBase(mDataId); if (null != table) { var tableDrop = Table.GetDropModel(table.DropModel); if (null != tableDrop) { SoundManager.Instance.PlaySoundEffect(tableDrop.SoundId); } } } IEnumerator Delay() { mState = State.Delay; var renderers = mModel.GetComponentsInChildren<Renderer>(); foreach (var renderer in renderers) { renderer.enabled = false; } yield return new WaitForSeconds(DelayTime); foreach (var renderer in renderers) { renderer.enabled = true; } DropToTargetPos(); } void DropToTargetPos() { mState = State.Droping; Vector3[] paths=new Vector3[3]; paths[0] = Position; paths[1] = (mTargetPos+Position)/2; paths[1].y = Position.y + DropHight; paths[2] = mTargetPos; iTween.MoveTo(gameObject, iTween.Hash("path", paths, "movetopath", true, "orienttopath", false, "time", DropTime, "easetype", iTween.EaseType.linear, "oncomplete", "DropOver")); } void DropOver() { this.StartCoroutine(DropOverStay()); } IEnumerator DropOverStay() { yield return new WaitForSeconds(DropOverDelayTime); mState = State.StayOnGround; PlayDropSound(); } public override void Destroy() { if(State.FlyToPlayer==mState) { return; } base.Destroy(); } public void FlyToPlayer() { if (null != mController) { mController.ShowModel(false); mController.ShowEffect(true); } var myPos = ObjManager.Instance.MyPlayer.Position; var dir = (Position-myPos).normalized; mControlPoint = Position + dir * ControlPointOffsetDistance; mControlPoint.y += ControlPointOffsetHeight; mControlPointMoveSpeed = ControlPointSpeed; mMoveSpeed = MoveSpeed; mControlPointReached = false; mState=State.FlyToPlayer; } }
原文:http://www.cnblogs.com/mrblue/p/4916695.html