直接贴代码了

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

  

Unity3d 制作物品平滑运动的更多相关文章

  1. Unity3D ShaderLab 模拟纹理运动

    Unity3D ShaderLab 模拟纹理运动 这一篇,我们要说到着色器上的uv贴图的滚动效果,这样的场景可以用在河流,瀑布,熔岩等效果.算是创建纹理动画的基础技术之一. 所以 准备一个新的着色器文 ...

  2. WPF编程,通过Path类型制作沿路径运动的动画一种方法。

    原文:WPF编程,通过Path类型制作沿路径运动的动画一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/de ...

  3. WPF编程,通过Path类型制作沿路径运动的动画另一种方法。

    原文:WPF编程,通过Path类型制作沿路径运动的动画另一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/d ...

  4. 【全面解禁!真正的Expression Blend实战开发技巧】第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条

    原文:[全面解禁!真正的Expression Blend实战开发技巧]第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条 这一章讲解FluidMoveBehavior的另一个应用, ...

  5. [0]尝试用Unity3d制作一个王者荣耀(持续更新)->游戏规划

    太得闲了于是想写个农药,虽然可能会失败但是还是要试一试. 因为是自学的不是Unity专业的可能表达语言会有些不标准!望见谅! 结构: 以组件式(比如说摇杆控制和玩家部分的编写是分离的,可以自由拼装)作 ...

  6. Unity3D制作3D虚拟漫游场景(二)

    传送门: Unity3D制作3D虚拟漫游场景(一) -------------------------------------------------------------------------- ...

  7. 利用Unity3D制作简易2D计算器

    利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...

  8. 高通vuforia+Unity3D 制作ar app

    很简单就可以用Unity3D做出增强现实的一个小例子 新人第一次写博客,若出现错误望指正^_^ 需要下载de东西: unity3d 5.0 http://unity3d.com/get-unity   ...

  9. 制作动画平滑过渡效果:《CSS3 Transition》

    W3C标准中对css3的transition这是样描述的:“css的transition允许css的属性值在一定的时间区间内平滑地过渡.这种效果可以在鼠标单击.获得焦点.被点击或对元素任何改变中触发, ...

随机推荐

  1. Java8初体验(一)lambda表达式语法

    感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 本文主要记录自己学习Java8的历程,方便大家一起探讨和自己的备忘.因为本人也是刚刚开始学习Java8,所以文中肯定有错误和理解 ...

  2. C语言strdup函数

    static RD_INLINE RD_UNUSED char *rd_strdup(const char *s) { #ifndef _MSC_VER char *n = strdup(s); #e ...

  3. 查看mysql数据库的数据引擎

    1, SHOW VARIABLES LIKE 'storage_engine'; 2,show table status from 数据库库名 where name='表名',例: mysql> ...

  4. php操作mysql数据库

    <span style="font-family:Arial,Helvetica,sans-serif">在php操作数据库过,会频繁对数据库进行各种操作,所以,php ...

  5. UTF-8-BOM

    https://www.zhihu.com/question/20167122 知乎 「带 BOM 的 UTF-8」和「无 BOM 的 UTF-8」有什么区别?网页代码一般使用哪个? http://b ...

  6. WCF--提示:异常消息为“传入消息的消息格式不应为“Raw”。此操作的消息格式应为 'Xml', 'Json'。

    Ajax调用WCF服务... 本来用 // $.getJSON("http://localhost:16625/Service1.svc/Article_GetInfo", { } ...

  7. 微信要革"传统电视"的命吗?

    除夕夜不知大家是否发现微信摇一摇界面下方的菜单变成4个了?“红包,人,歌曲,电视”,红包和电视是新增的,几天之后红包这个菜单消失了,电视菜单还在,能够摇出一些电视台的直播节目单,以往的摇电视借用的是摇 ...

  8. Linux(Ubuntu)安装并破解 SecureFX

    根据Linux(Ubuntu)下面SecureCRT 完全破解(地址:http://www.boll.me/archives/680) 添加了Linux(Ubuntu)下面SecureFX 完全破解, ...

  9. SCP命令

    \ svn 删除所有的 .svn文件 find . -name .svn -type d -exec rm -fr {} \; linux之cp/scp命令+scp命令详解   名称:cp 使用权限: ...

  10. Oracle添加数据报文字与格式字符串不匹配错误

    今天在学习Oracle时碰到一个错:文字与格式字符串不匹配. 我在Oracle数据库中创建了一张表: --创建员工表employee create table employee ( empon ) n ...