参考链接:http://game.ceeger.com/Components/class-BoxCollider.html
http://game.ceeger.com/Components/RigidbodySleeping.html
http://game.ceeger.com/Components/class-CharacterController.html
碰撞器:Collider
触发器:勾选了isTrigger的Collider
在unity中,碰撞器有三种,相对应的,触发器也有三种。
碰撞产生的条件:
两个碰撞器,且至少有一个是刚体碰撞器(不包含运动学刚体碰撞器)
触发产生的条件:
两个碰撞器,且至少有一个是刚体碰撞器(包含运动学刚体碰撞器),至少有一个勾选了isTrigger
最重要的一点:除了满足上述的条件之外,必须是具有刚体的一方去碰撞!没有刚体的去碰撞静止的具有刚体的,将不会发生反应!这是因为刚体休眠!
控制器不会对加在它自身上的力做出反应,也不会自动推开其他刚体。如果想让角色控制器推开其他刚体或者对象,你可以在对象附加的脚本中添加OnControllerColliderHit()函数,这样对它们施加力就能够产生碰撞。
Character Controller相当于刚体碰撞器,但是没有刚体那样的物理特性,照样会触发OnCollision和OnTrigger的函数,照样会有刚体休眠!Character Controller运动时要使用Move或者SimpleMove才会进行相应的检测。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1.transform.Find
通过名字查找子物体并返回它。查找的范围不包括自身和子物体的子物体,只包含子物体。
给Cube添加脚本,如果想查找Cube2,则为:transform.Find("Cube2");如果想查找Cube3,则为:transform.Find("Cube2/Cube3")
transform.Find可以找到isActive为false的物体,但前提是该物体的根物体必须isActive为true。因此,可以创建一个isActive为true的空物体,让isActive为false的物体成为空物体的子物体,再使用transform.Find就可以找到了。
查找Cube:(GameObject.Find("GameObject").transform.Find("Cube")
注意一点,GameObject.Find无法查找isActive为false的物体。
2.transform.GetComponentInChildren与transform.GetComponentsInChildren
搜索的范围包括自身,但不包括isActive为false的子物体
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
官网文档:http://docs.unity3d.com/Manual/PlatformDependentCompilation.html
UNITY_EDITOR | Define for calling Unity Editor scripts from your game code. |
UNITY_EDITOR_WIN | Platform define for editor code on Windows. |
UNITY_EDITOR_OSX | Platform define for editor code on Mac OSX. |
UNITY_STANDALONE_OSX | Platform define for compiling/executing code specifically for Mac OS (This includes Universal, PPC and Intel architectures). |
UNITY_STANDALONE_WIN | Use this when you want to compile/execute code for Windows stand alone applications. |
UNITY_STANDALONE_LINUX | Use this when you want to compile/execute code for Linux stand alone applications. |
UNITY_STANDALONE | Use this to compile/execute code for any standalone platform (Mac, Windows or Linux). |
UNITY_WEBPLAYER | Platform define for web player content (this includes Windows and Mac Web player executables). |
UNITY_WII | Platform define for compiling/executing code for the Wii console. |
UNITY_IOS | Platform define for compiling/executing code for the iOS platform. |
UNITY_IPHONE | Deprecated. Use UNITY_IOS instead. |
UNITY_ANDROID | Platform define for the Android platform. |
UNITY_PS3 | Platform define for running PlayStation 3 code. |
UNITY_PS4 | Platform define for running PlayStation 4 code. |
UNITY_XBOX360 | Platform define for executing Xbox 360 code. |
UNITY_XBOXONE | Platform define for executing Xbox One code. |
UNITY_BLACKBERRY | Platform define for a Blackberry10 device. |
UNITY_WP8 | Platform define for Windows Phone 8. |
UNITY_WP8_1 | Platform define for Windows Phone 8.1. |
UNITY_WSA | Platform define for Windows Store Apps (additionally NETFX_CORE is defined when compiling C# files against .NET Core). |
UNITY_WSA_8_0 | Platform define for Windows Store Apps when targeting SDK 8.0. |
UNITY_WSA_8_1 | Platform define for Windows Store Apps when targeting SDK 8.1. |
UNITY_WINRT | Equivalent to UNITY_WP8 | UNITY_WSA. |
UNITY_WINRT_8_0 | Equivalent to UNITY_WP8 | UNITY_WSA_8_0. |
UNITY_WINRT_8_1 | Equivalent to UNITY_WP_8_1 | UNITY_WSA_8_1. It’s also defined when compiling against Universal SDK 8.1. |
UNITY_WEBGL | Platform define for WebGL. |
UNITY_2_6 | Platform define for the major version of Unity 2.6. |
UNITY_2_6_1 | Platform define for specific version 2.6.1. |
UNITY_3_0 | Platform define for the major version of Unity 3.0. |
UNITY_3_0_0 | Platform define for specific version 3.0.0. |
UNITY_3_1 | Platform define for major version of Unity 3.1. |
UNITY_3_2 | Platform define for major version of Unity 3.2. |
UNITY_3_3 | Platform define for major version of Unity 3.3. |
UNITY_3_4 | Platform define for major version of Unity 3.4. |
UNITY_3_5 | Platform define for major version of Unity 3.5. |
UNITY_4_0 | Platform define for major version of Unity 4.0. |
UNITY_4_0_1 | Platform define for specific version 4.0.1. |
UNITY_4_1 | Platform define for major version of Unity 4.1. |
UNITY_4_2 | Platform define for major version of Unity 4.2. |
UNITY_4_3 | Platform define for major version of Unity 4.3. |
UNITY_4_5 | Platform define for major version of Unity 4.5. |
UNITY_4_6 | Platform define for major version of Unity 4.6. |
UNITY_5_0 | Platform define for major version of Unity 5.0. |
using UnityEngine; using System.Collections; public class PlatformDefines : MonoBehaviour { void Start() { #if UNITY_EDITOR Debug.Log("Unity Editor"); #endif #if UNITY_IPHONE Debug.Log("Iphone"); #endif #if UNITY_STANDALONE_OSX Debug.Log("Stand Alone OSX"); #endif #if UNITY_STANDALONE_WIN Debug.Log("Stand Alone Windows"); #endif } }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
打击感的体现:
1.被击特效:怪物被击中时迸出的火花或者血液,这个不必多解释。如果不同材质的怪物能配合与之对应的被击音效及不同的被击特效,“刀刀入肉”的感觉会非常强。可试着像魔兽3一样将怪物区别为 血肉、木头、金属等几个大类,区别表现。
2.镜头震动:攻击到怪物的一瞬间屏幕会有轻微抖动,暗黑3把这一技巧的价值发挥得淋漓尽致,让这个本来毫无打击感的游戏看起来动感十足。虽然技术实现上没有难度,但实现时须注意抖动的幅度和频率,否则很容易让观众头晕。作者应该是有加轻微的抖动,但幅度比较小,加上镜头一直跟随角色位移,所以震动效果并不明显。另外,不同强度的攻击最好配以不同强度的震动。
3.打击停滞:这一技巧在很多格斗游戏中都有使用,最终怪物猎人将它发扬光大。实现原理也不复杂:武器碰撞到怪物的瞬间,主角的动作会瞬间停滞若干帧,以模拟怪物对武器的“反作用力”。加入这种效果后,在一个攻击动作中打击到多个敌人时,会有“横扫千军”的爽快的体验。当然,这是基于你的打击判定是有真实的“碰撞检测”的情况。在arpg中,即使没有像动作游戏中那种精确碰撞检测,也可以通过一些小手段来模拟这种效果。
4.被击抖动:被打击的怪物会朝受力方向移动,这点类似击退,但是在短时间内它会再弹回到原位,以此模拟怪物本身的“弹性”。这一技巧在拳皇中有出现,尤其是在版边无限连的时候,经常看到对手一直在那里销魂得抖啊抖。
5.击退:楼主已经应用了这个技巧,但我还想补充一些细节。击退是模拟怪物在地上滑行的一个过程。所以如果要让这个过程更加真实,最好不要将它做成一个匀速运动。应该做一个减速然后骤停的过程,来模拟地面“摩擦力”和怪物之间的相互作用,具体物理细节就不讨论了,但想要完美实现,务必同时考虑到“动摩擦”和“静摩擦”的存在。另外,是否击退以及击退距离可做适当随机。远距离的击退还可以加入随机的抛物线,简单的随机能让游戏看起来更加真实。如果在意细节表现,还可以让被击目标在滑行时拖出烟雾特效,效果更佳。
6.对比:在强攻击中(比如连击中的终结move)出现更多更强效果,而其他弱攻击可以适当减弱或者去除一些打击效果(比如击退、震动、停滞)。有对比才有强弱的感觉,再好的打击效果如果一直看也会产生视觉疲劳,偶尔出一下特别强的打击效果反而能震撼到玩家。最佳的表现方式还是要反复体验才能找到的。
7.其他细节:
怪物死了之后也最好也有个击退效果的,而不是原地播死亡动作,而且这个击退距离可能会更夸张,因为怪物已死,不会主动保持平衡了。
击中判定也需要优化,武器没有碰到怪就判为命中,也会影响整体打击感。
作者有做貌似“浮空”的效果,但浮空时怪物最好后仰一定角度并保持被击的pose,同时配合脚下影子才能较好的被玩家辨认出来(战斗场景中怪物的影子被去除了,是考虑到性能问题?)。
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
AssetBundle
一.打包AssetBundle
1.BuildPipeline.BuildAssetBundle(将Assets打包)
2.BuildPipeline.BuildStreamedSceneAssetBundle(将Scene打包)
3.BuildPipeline.BuildAssetBundleExplicitAssetNames(将Assets打包,并指定自定义的名字)
BuildPipeline.BuildAssetBundle
static function BuildAssetBundle (mainAsset : Object, assets :Object[], pathName : string, options :BuildAssetBundleOptions =BuildAssetBundleOptions.CollectDependencies |BuildAssetBundleOptions.CompleteAssets, targetPlatform :BuildTarget =BuildTarget.WebPlayer) : bool
mainAsset :指定AssetBundle文件中的主要资源,可通过AssetBundle.mainAsset读取
assets :指定AssetBundle文件中包含的资源
BuildPipeline.BuildStreamedSceneAssetBundle
static function BuildStreamedSceneAssetBundle(levels: string[], locationPath: string, target: BuildTarget) : string
levels:场景名称
BuildPipeline.BuildAssetBundleExplicitAssetNames
static function BuildAssetBundleExplicitAssetNames (assets : Object[], assetNames : string[],pathName : string, options : BuildAssetBundleOptions = BuildAssetBundleOptions.CollectDependencies |BuildAssetBundleOptions.CompleteAssets, targetPlatform :BuildTarget = BuildTarget.WebPlayer) : bool
BuildAssetBundleOptions
http://docs.unity3d.com/ScriptReference/BuildAssetBundleOptions.html
创建AssetBundle之间的依赖
先将mat打包到一个单独的AB,然后让包含cube和cylinder的两个AB分别依赖于该AB
二.下载AssetBundle
1.new WWW(url) 非缓存机制
2.WWW.LoadfromCacheorDownload 缓存机制
三.加载AssetBundle至内存
1.WWW.assetbundle
2.AssetBundle.CreatFromFile 从磁盘文件创建一个AB文件的内存对象,仅支持非压缩格式的AB
3.AssetBundle.CreatFromMemory 从内存数据流创建AB内存对象
四.加载AssetBundle中的Asset
A.普通AssetBundle
1.AssetBundle.Load 通过名字加载某个Asset
2.AssetBundle.LoadAsync 适用于加载一个较大的Asset或者同时加载多个Asset
3.AssetBundle.LoadAll 一次性加载AB文件中所有的Assets
B.场景AssetBundle
1.Application.LoadLevel
2.Application.LoadLevelAsync
3.Application.LoadLevelAdditive(不摧毁之前的场景)
4.Application.LoadLevelAdditiveAsync
五.卸载AssetBundle
AssetBundle.UnLoad
卸载释放bundle中所有序列化数据。当unloadAllLoaderObjects为假,bundle内的序列化数据将被释放,但是任何从这个bundle中实例化的物体都将完好。当然,你不能从这个bundle中加载更多物体。当unloadAllLoaderObjects为真,所有从该bundle中加载的物体也将被销毁。如果场景中有游戏物体引用该资源,那么引用也会丢失。推荐设置为false
六.卸载Asset
Resource.UnloadUnusedAssets
AssetBundle的内存管理
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
ScriptableObject类型经常用于存储一些unity3d本身不可以打包的一些object,比如字符串,一些类对象等。用这个类型的子类型,则可以用BuildPipeline打包成assetbundle包供后续使用,非常方便。
通常,可以用BuildPipeline.BuildAssetBundle打包资源,这些资源包括模型、纹理、贴图等。其实也可以打包ScriptableObject,而ScriptableObject中可以存储任何数据类型。
这其实是把整个对象实例打包,如果ScriptableObject属性中包括其他的类实例,则这些类需加上[Serializable]序列化。通过这种方法,可以将系统需要的数据(如角色分类、matrix4x4数据等等)打包,加载后直接转换为预定的类型,具有更高的效率。
using UnityEngine; using System.Collections; public class TestSO : ScriptableObject { public int id; public string name; public Vector3 pos; public void Init() { id = 1; name = "hello"; pos = new Vector3(0,1,2); } }
using UnityEngine; using System.Collections; using UnityEditor; public class TestSO2 { [MenuItem("Window/TestSO2")] public static void A() { TestSO testSO = ScriptableObject.CreateInstance<TestSO>(); testSO.Init(); string path = "Assets/testSO.asset"; AssetDatabase.CreateAsset(testSO,path); AssetDatabase.Refresh(); Object o = AssetDatabase.LoadAssetAtPath(path,typeof(TestSO)); BuildPipeline.BuildAssetBundle(o, null, "Assets/testSO.assetbundle"); AssetDatabase.Refresh(); } }
using UnityEngine; using System.Collections; public class TestSO3 : MonoBehaviour { void Start () { StartCoroutine(Load()); } IEnumerator Load() { string url = "file:///" + Application.dataPath + "/testSO.assetbundle"; WWW www = new WWW(url); yield return www; TestSO a = www.assetBundle.mainAsset as TestSO; Debug.Log("id:" + a.id + " name:" + a.name + " pos:" + a.pos); } }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
using UnityEngine; using System.Collections; public class TestLayerMask : MonoBehaviour { public LayerMask layerMask; // Update is called once per frame void Update () { if (Input.GetMouseButtonDown(0)) { Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; //只有layerMask包含的层才能接受射线检测 if (Physics.Raycast(ray, out hit, 1000, layerMask)) print(hit.transform.name); //只有第十层才能接受射线检测 //if (Physics.Raycast(ray, out hit, 1000, 1 << 10)) // print(hit.transform.name); //除了第十层之外,其余层都能接受射线检测 //if (Physics.Raycast(ray, out hit, 1000, ~1 << 10)) // print(hit.transform.name); //nothing:0,everything:-1 //builtin layer0:2^0,builtin layer1:2^1,builtin layer2:2^2 //如果value为7,则代表builtin layer0,1,2被选中 //print(layerMask.value); } } }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Mecanim
模型导入场景后变暗的解决方法:
a.模型默认的shader是diffuse,要进行修改,一般模型改成Unlit—Texture,透明的模型改成Unlit—transparent
b.找到Skinned Mesh Renderer组件,勾选Use Light Probes
1.
创建Avatar:
在Rig选项卡将Animation Type改为Humanoid,选择Avatar Definition,然后点击Apply,
如果创建成功,会看到Configure左边有个勾,并且模型文件下多了个Avatar
配置Avatar:
点击Configure,会看到Mapping和Muscles两个选项卡
Mapping:确定骨骼的映射关系
Muscles:确定部位的运动范围
2.
动画Mask:
在Animations选项卡下有个Mask,点击部位即可禁止该部位运动
动画Mask与上面Muscles选项卡的区别:
动画Mask:仅影响该动画
Muscles:影响所有动画
3.
动画Retargeting:
作用:可以将一个动画应用到多个模型中
条件:为模型创建Avatar,在Animator Controller的动画片段中选择动画
(即使动画不属于该模型,该模型也可播放该动画)
4.
动画片段循环设置:
在Animations选项卡下有四个灯,绿灯表示该动画片段循环程度比较好(红灯则代表比较差),
作用就是当对一整段动画进行切割时,可以作指示作用,指示当前的动画切割是否合适,
绿灯时,一般要勾选对应的Bake Into Pose。
另外可以设置播放动画时的位置以及旋转(可以解决动画播放浮空问题)
http://game.ceeger.com/Manual/RootMotion.html
5.
Apply Root Motion 与 Bake Into Pose
美术在制作动画时会带有位移旋转,但动画中的位移旋转并不会反映到transform组件,如果想反映到transform组件,
则要勾选Apply Root Motion。这里以一个模型向上跳的动画为例:
Bake Into Pose:是否将位移旋转应用到动画上(若不勾选Apply Root Motion,则只是播放动画,transform组件数据不变)
对于Root Transform Position (Y),若勾选该项,表示将y轴上的位移应用到动画上,播放动画时模型向上跳;
若不勾选该项,表示不将y轴上的位移应用到动画上,播放动画时模型原地跳
Apply Root Motion:是否将位移旋转应用到transform组件上
若勾选该项,则动画中的位移旋转将会被应用到transform组件,否则不会
再比如一个模型向前行走的动画(动画含位移,不是原地走),以Root Transform Position (XZ)为例
a.勾选Bake Into Pose,不勾选Apply Root Motion
播放动画,模型向前走,但transform组件不变,若再次播放动画,模型会回到原点再向前走
b.勾选Bake Into Pose,勾选Apply Root Motion
播放动画,模型向前走,transform组件变,若再次播放动画,模型在当前点向前走
c.不勾选Bake Into Pose,勾选Apply Root Motion
同b,但其实模型是原地走,配合transform组件。
d.不勾选Bake Into Pose,不勾选Apply Root Motion
原地走
6.
动画Curves:
在Animations选项卡下有个Curves,可以通过曲线编辑器编辑曲线
在Animator窗口下可以添加动画参数,如果参数的名字和曲线的名字相同,
则参数的值就是曲线的值
7.
OnAnimatorMove()
http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorMove.html
勾选Apply Root Motion,表示动画中的位移旋转由unity自动计算并且应用到transform组件中,
不勾选即表示不计算不应用,当使用这个函数时,表示由用户自己自定义去实现这个过程,
此时你会发现Apply Root Motion右边的勾变成了Handled by Script
8.
Animator组件(unity5版本):
Update Mode:
Normal:当Update被调用时,Animator也会被调用。受timescale影响
Animate Physics:当FixedUpdate被调用时,Animator也会被调用。模拟物理效果
Unscaled Time:当Update被调用时,Animator也会被调用。不受timescale影响
Culling Mode(剔除模式,动画不在摄像机范围时怎么处理,用于优化性能):
Always animate:不剔除
Cull Update Transform:只更新transform
Cull Completely:完全剔除
9.
Blend Tree:
将多个动画混合,并用参数控制这些动画的过渡
Blend Type为1D时:使用一个float参数控制动画的过渡。如果没有float参数,那么需要新建一个,
并且在Parameter栏指定它
10.
动画层:
作用:控制不同部位的动画,可以实现部位动画融合(例如边走边射击),需要Avatar Mask
注意设置层的权重,0表示该层不起作用,1表示该层完全起作用
动画层的序号越高,则越优先执行。Base Layer序号为0,每新建一个层,序号增加1。
Blending:
Override:重写上一层,即优先执行该层
Additive:与上一层叠加,即层动画融合
11.
IK(反向动力学):
与IK相关的操作要写在OnAnimatorIK(int layerIndex)函数中,同时要勾选层中的IK Pass才能起作用
http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnAnimatorIK.html
设置权重:0表示关闭IK,1表示完全开启IK
layerIndex:Base Layer为0
12.
目标匹配(MatchTarget函数的使用,例如可以实现攀爬效果):
http://docs.unity3d.com/ScriptReference/Animator.MatchTarget.html
13.
注视位置:Animator.SetLookAtPosition
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////