zoukankan      html  css  js  c++  java
  • Unity3d 制作物品平滑运动

    直接贴代码了

    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;
    	}
    
    }
    

      

  • 相关阅读:
    Python进程池multiprocessing.Pool的用法
    基于opencv的车牌提取项目
    Srapy 爬取知乎用户信息
    Scrapy框架简介及小项目应用
    豆瓣爬取图书标签
    CSS选择器使用
    关于 urlencode 的使用和 json 模块的介绍
    urllib库使用方法
    猫眼电影的各种爬取方法
    淘宝商品信息爬取
  • 原文地址:https://www.cnblogs.com/mrblue/p/4916695.html
Copyright © 2011-2022 走看看