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;
} }
Unity3d 制作物品平滑运动的更多相关文章
- Unity3D ShaderLab 模拟纹理运动
Unity3D ShaderLab 模拟纹理运动 这一篇,我们要说到着色器上的uv贴图的滚动效果,这样的场景可以用在河流,瀑布,熔岩等效果.算是创建纹理动画的基础技术之一. 所以 准备一个新的着色器文 ...
- WPF编程,通过Path类型制作沿路径运动的动画一种方法。
原文:WPF编程,通过Path类型制作沿路径运动的动画一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/de ...
- WPF编程,通过Path类型制作沿路径运动的动画另一种方法。
原文:WPF编程,通过Path类型制作沿路径运动的动画另一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/d ...
- 【全面解禁!真正的Expression Blend实战开发技巧】第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条
原文:[全面解禁!真正的Expression Blend实战开发技巧]第九章 FluidMoveBehavior完全解析之二平滑运动的滚动条 这一章讲解FluidMoveBehavior的另一个应用, ...
- [0]尝试用Unity3d制作一个王者荣耀(持续更新)->游戏规划
太得闲了于是想写个农药,虽然可能会失败但是还是要试一试. 因为是自学的不是Unity专业的可能表达语言会有些不标准!望见谅! 结构: 以组件式(比如说摇杆控制和玩家部分的编写是分离的,可以自由拼装)作 ...
- Unity3D制作3D虚拟漫游场景(二)
传送门: Unity3D制作3D虚拟漫游场景(一) -------------------------------------------------------------------------- ...
- 利用Unity3D制作简易2D计算器
利用Unity3D制作简易2D计算器 标签(空格分隔): uiniy3D 1. 操作流程 在unity3DD中创建一个新项目 注意选择是2D的(因为默认3D) 在Assets框右键新建C#脚本 在新建 ...
- 高通vuforia+Unity3D 制作ar app
很简单就可以用Unity3D做出增强现实的一个小例子 新人第一次写博客,若出现错误望指正^_^ 需要下载de东西: unity3d 5.0 http://unity3d.com/get-unity ...
- 制作动画平滑过渡效果:《CSS3 Transition》
W3C标准中对css3的transition这是样描述的:“css的transition允许css的属性值在一定的时间区间内平滑地过渡.这种效果可以在鼠标单击.获得焦点.被点击或对元素任何改变中触发, ...
随机推荐
- iOS开发 关于SEL的简单总结
SEL就是对方法的一种包装.包装的SEL类型数据它对应相应的方法地址,找到方法地址就可以调用方法.在内存中每个类的方法都存储在类对象中,每个方法都有一个与之对应的SEL类型的数据,根据一个SEL数据就 ...
- 【采集层】Kafka 与 Flume 如何选择--转自悟性的博文
[采集层]Kafka 与 Flume 如何选择 收藏 悟性 发表于 2年前 阅读 23167 收藏 16 点赞 4 评论 1 摘要: Kafka, Flume 采集层 主要可以使用Flume, Kaf ...
- CFgym Board Queries (旋转、翻转简化)
http://codeforces.com/gym/100497 codeforces 2014-2015 CT S02E04: Codeforces Trainings Season 2 Episo ...
- 如何使用UltraCompare对比两个文件夹内容差异
http://jingyan.baidu.com/article/cb5d6105e13599005c2fe0f8.html
- 系统研究Airbnb开源项目airflow
开源项目airflow的一点研究 调研了一些几个调度系统, airflow 更满意一些. 花了些时间写了这个博文, 这应该是国内技术圈中最早系统性研究airflow的文章了. 转载请注明出处 htt ...
- STM32 之 NVIC(中断向量、优先级) 简述
一.背景 需要使用STM32的CAN进行通信,经过一系列配置后,已可正常收发,还剩下一个CAN通信的错误处理.可错 误中断使能寄存器已经配置使能了,出错后就是无法进入"CAN1_SCE_IR ...
- Cotex-M3内核LPC17xx系列时钟及其配置方法
一.背景: 最近正在接手一个项目,核心芯片既是LPC17XX系列MCU,内核为ARM的Cotex-M3内核. 想要玩转一个MCU,就一定得搞定其时钟! 时钟对MCU而言,就好比人类的心脏.由其给AHB ...
- 微信小程序开放公测了 晚上又可以通宵搞代码了
就在刚刚22:15分,微信公众平台的服务号发来好消息说小程序开放公测了,喜大普奔啊!!!码农们晚上又可以通宵搞测试了.之前还猜测16日微信小论坛小程序专场上会公布,没想到提前了那么多天,效率挺高的,而 ...
- Hibernate框架之入门案例
今天终于开始学习了三大框架的其中一个框架,Hibernate框架,在这里不去讲Hibernate框架的一些基础概念了,直接切入代码,带大家了解一下Hibernate能干什么, Hibernate的人们 ...
- 使用xp光盘修复系统的方法步骤
对于使用Windows XP系统的朋友来说,当系统出现崩溃或者系统使用时出现一些莫名其妙的错误时,你采用什么方法解决呢?一般都是采用重装系统或者使用Ghost恢复等. 但是使用这些方法各有缺陷,比如重 ...