直接贴代码了
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;
}
}