请教关于unity 加载prefab的prefab的问题

新人请教问题【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:77,368贴子:
新人请教问题收藏
为什么打不开,每次都要重装
江苏盘锦天燃气模温机,一台省得让你怀疑人生的燃气锅炉
全盘杀毒,我之前也这样,杀过后就恢复了
点击work offline
登录百度帐号推荐应用程序写累了,就来玩玩酷跑小游戏吧,嘿嘿。
雨松MOMO送你一首歌曲,嘿嘿。
Unity2D研究院之自动生成动画、AnimationController、Prefab(一)
Unity2D研究院之自动生成动画、AnimationController、Prefab(一)
围观59946次
编辑日期: 字体:
国庆了,回家了。时刻还是要吃一颗学习的心,在家了也要抽出时间好好学习一下。之前MOMO一直没研究过Unity2D,今天研究了一下,还是把自己今天的研究笔记记录下来。现在网络上已经有很多Unity2D的技术分享了,我这篇主要说说自动生成先关的东西。
Unity2D的制作流程
1、拿到美术给的帧动画
2、打开Animation windows 手动创建动画文件
3、创建AnimationController 手动连线
4、创建Prefab文件。
这也太麻烦了。全都手动来美术每次给你好几十个动画资源那岂不是要累死程序员了。所以我们不能手动,必须自动。
如下图所示,先看看我生成出来的结果。
我们的目标是Raw文件夹下放所有美术提供的帧动画,每个文件夹就是一组帧动画,文件夹名子就是动画的名子,代码如下所示。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
using UnityEngine;using System.Collections;using System.IO;using System.Collections.Generic;using UnityEditor;using UnityEditorInternal;&public class BuildAnimation : Editor {&&&&&//生成出的Prefab的路径 private static string PrefabPath = "Assets/Resources/Prefabs"; //生成出的AnimationController的路径 private static string AnimationControllerPath = "Assets/AnimationController"; //生成出的Animation的路径 private static string AnimationPath = "Assets/Animation";&&&&//美术给的原始图片路径 private static string ImagePath = Application.dataPath +"/Raw";& [MenuItem("Build/BuildAnimaiton")] static void BuildAniamtion()
DirectoryInfo raw = new DirectoryInfo (ImagePath);
foreach (DirectoryInfo dictorys in raw.GetDirectories())
List&AnimationClip& clips = new List&AnimationClip&();
foreach (DirectoryInfo dictoryAnimations in dictorys.GetDirectories())
//每个文件夹就是一组帧动画,这里把每个文件夹下的所有图片生成出一个动画文件
clips.Add(BuildAnimationClip(dictoryAnimations));
//把所有的动画文件生成在一个AnimationController里
AnimatorController controller = BuildAnimationController(clips,dictorys.Name);
//最后生成程序用的Prefab文件
BuildPrefab(dictorys,controller);
}&& static AnimationClip BuildAnimationClip(DirectoryInfo dictorys) {
string animationName = dictorys.Name;
//查找所有图片,因为我找的测试动画是.jpg
FileInfo []images&&= dictorys.GetFiles("*.jpg");
AnimationClip clip = new AnimationClip();
AnimationUtility.SetAnimationType(clip,ModelImporterAnimationType.Generic);
EditorCurveBinding curveBinding = new EditorCurveBinding();
curveBinding.type = typeof(SpriteRenderer);
curveBinding.path="";
curveBinding.propertyName = "m_Sprite";
ObjectReferenceKeyframe[] keyFrames = new ObjectReferenceKeyframe[images.Length];
//动画长度是按秒为单位,1/10就表示1秒切10张图片,根据项目的情况可以自己调节
float frameTime = 1/10f;
for(int i =0; i& images.Length; i++){
Sprite sprite = Resources.LoadAssetAtPath&Sprite&(DataPathToAssetPath(images[i].FullName));
keyFrames[i] =&& new ObjectReferenceKeyframe ();
keyFrames[i].time = frameTime *i;
keyFrames[i].value = sprite;
//动画帧率,30比较合适
clip.frameRate = 30;&&&&&&&&&//有些动画我希望天生它就动画循环
if(animationName.IndexOf("idle") &=0 )
//设置idle文件为循环动画
SerializedObject serializedClip = new SerializedObject(clip);
AnimationClipSettings clipSettings = new AnimationClipSettings(serializedClip.FindProperty("m_AnimationClipSettings"));
clipSettings.loopTime = true;
serializedClip.ApplyModifiedProperties();
string parentName = System.IO.Directory.GetParent(dictorys.FullName).Name;
System.IO.Directory.CreateDirectory(AnimationPath +"/"+parentName);
AnimationUtility.SetObjectReferenceCurve(clip,curveBinding,keyFrames);
AssetDatabase.CreateAsset(clip,AnimationPath +"/"+parentName +"/" +animationName+".anim");
AssetDatabase.SaveAssets();
return clip; }& static AnimatorController BuildAnimationController(List&AnimationClip& clips ,string name) {
AnimatorController animatorController = AnimatorController.CreateAnimatorControllerAtPath(AnimationControllerPath +"/"+name+".controller");
AnimatorControllerLayer layer = animatorController.GetLayer(0);
UnityEditorInternal.StateMachine sm = layer.stateMachine;
foreach(AnimationClip newClip in clips)
State&&state = sm.AddState(newClip.name);
state.SetAnimationClip(newClip,layer);
Transition trans = sm.AddAnyStateTransition(state);
trans.RemoveCondition(0);
AssetDatabase.SaveAssets();
return animatorController; }& static void BuildPrefab(DirectoryInfo dictorys,AnimatorController animatorCountorller) {
//生成Prefab 添加一张预览用的Sprite
FileInfo images&&= dictorys.GetDirectories()[0].GetFiles("*.jpg")[0];
GameObject go = new GameObject();
go.name = dictorys.Name;
SpriteRenderer spriteRender =go.AddComponent&SpriteRenderer&();
spriteRender.sprite = Resources.LoadAssetAtPath&Sprite&(DataPathToAssetPath(images.FullName));
Animator animator = go.AddComponent&Animator&();
animator.runtimeAnimatorController = animatorCountorller;
PrefabUtility.CreatePrefab(PrefabPath+"/"+go.name+".prefab",go);
DestroyImmediate(go); }&& public static string DataPathToAssetPath(string path) {
if (Application.platform == RuntimePlatform.WindowsEditor)
return path.Substring(path.IndexOf("Assets\\"));
return path.Substring(path.IndexOf("Assets/")); }&& class AnimationClipSettings {
SerializedProperty m_Property;
private SerializedProperty Get (string property) { return m_Property.FindPropertyRelative(property); }
public AnimationClipSettings(SerializedProperty prop) { m_Property = prop; }
public float startTime&& { get { return Get("m_StartTime").floatValue; } set { Get("m_StartTime").floatValue = value; } }
public float stopTime { get { return Get("m_StopTime").floatValue; }&&set { Get("m_StopTime").floatValue = value; } }
public float orientationOffsetY { get { return Get("m_OrientationOffsetY").floatValue; } set { Get("m_OrientationOffsetY").floatValue = value; } }
public float level { get { return Get("m_Level").floatValue; } set { Get("m_Level").floatValue = value; } }
public float cycleOffset { get { return Get("m_CycleOffset").floatValue; } set { Get("m_CycleOffset").floatValue = value; } }
public bool loopTime { get { return Get("m_LoopTime").boolValue; } set { Get("m_LoopTime").boolValue = value; } }
public bool loopBlend { get { return Get("m_LoopBlend").boolValue; } set { Get("m_LoopBlend").boolValue = value; } }
public bool loopBlendOrientation { get { return Get("m_LoopBlendOrientation").boolValue; } set { Get("m_LoopBlendOrientation").boolValue = value; } }
public bool loopBlendPositionY { get { return Get("m_LoopBlendPositionY").boolValue; } set { Get("m_LoopBlendPositionY").boolValue = value; } }
public bool loopBlendPositionXZ { get { return Get("m_LoopBlendPositionXZ").boolValue; } set { Get("m_LoopBlendPositionXZ").boolValue = value; } }
public bool keepOriginalOrientation { get { return Get("m_KeepOriginalOrientation").boolValue; } set { Get("m_KeepOriginalOrientation").boolValue = value; } }
public bool keepOriginalPositionY { get { return Get("m_KeepOriginalPositionY").boolValue; } set { Get("m_KeepOriginalPositionY").boolValue = value; } }
public bool keepOriginalPositionXZ { get { return Get("m_KeepOriginalPositionXZ").boolValue; } set { Get("m_KeepOriginalPositionXZ").boolValue = value; } }
public bool heightFromFeet { get { return Get("m_HeightFromFeet").boolValue; } set { Get("m_HeightFromFeet").boolValue = value; } }
public bool mirror { get { return Get("m_Mirror").boolValue; } set { Get("m_Mirror").boolValue = value; } } }&}
因为新版的动画系统Unity没有提供直接的API来设置动画的循环状态,所以我们只能通过写文件的形式来修改动画的天生属性。需要用到自己写封装的类 AnimationClipSettings 具体方法请看上面的代码。
有了自动生成动画的代码,就不怕美术一次给你多少组图片,或者更新了多少组图片都能很快的生成出来。
随便写一条测试脚本,来测试一下播放动画。
12345678910111213141516171819202122
using UnityEngine;using System.Collections;&public class NewBehaviourScript : MonoBehaviour {& Animator animator ;
void Start ()
animator = GetComponent&Animator&(); }&& void OnGUI() {
if(GUILayout.Button("idle"))
animator.Play("idle");&
动画播放的很正常的。
代码下载地址:
欢迎大家一起讨论unity2d游戏开发,如果您有更好的方法或者建议欢迎在下面给我留言,谢谢。
本文固定链接:
转载请注明:
雨松MOMO提醒您:亲,如果您觉得本文不错,快快将这篇文章分享出去吧 。另外请点击网站顶部彩色广告或者捐赠支持本站发展,谢谢!
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
如果您愿意花10块钱请我喝一杯咖啡的话,请用手机扫描二维码即可通过支付宝直接向我捐款哦。
您可能还会对这些文章感兴趣!请教,关于unity的材质问题【unity3d吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:77,368贴子:
请教,关于unity的材质问题收藏
最近在战机世界提取出模型和贴图文件,其中主要有base,normal map和一个细节文件decal,要使飞机能够达到比较理想的状态需要用到bumped specular和decal这两种shader,那么怎么才能把这两种结合起来应用到一种材质啊?
江苏盘锦天燃气模温机,一台省得让你怀疑人生的燃气锅炉
需要自己写shader来实现啦~~
登录百度帐号推荐应用【厚积薄发】技术分享(六十一)|优化Shader预加载| MMO游戏资源规范|GC分配定位...
我们将从日常技术交流中精选若干个开发相关的问题,建议阅读时间15分钟,认真读完必有收获。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。
UWA QQ群:
UWA 问答社区:
Unity5.4.1中,我将需要的Shader打到一个AssetBundle包中(包含一个关联了所有Shader的Shader Variants),分别用Shader.WarmupAllShaders和ShaderVariantCollection.WarmUp两种方式进行预加载,后者耗时更少。
这里用了Standard Shader做的测试,可以看到真机上两种方式耗时差距是非常大的。请问,确实是ShaderVariantCollection的效率更高,还是我测试方法有问题?
测试代码:
Shader的AB包里的内容:
A:根据官方的文档的描述,确实是ShaderVariantCollection的效率更高,详见:
因为在ShaderVariantCollection中,是可以给每个Shader添加指定的Keyword的,ShaderVariantCollection.WarmUp的调用只会对ShaderVariantCollection中指定的Keyword进行Warmup操作;而Shader.WarmupAllShaders则是对所有的Keyword全部进行Warmup操作(其中大多数很可能都不会用到)。
因此在Shader.WarmupAllShaders的文档中也提到,建议使用ShaderVariantCollection.Warmup来进行细粒度的Warmup操作,避免大量多余的Keyword被Warmup,造成严重的卡顿,大家可以参考下文:
此问答来自于UWA 问答社区:
如您对该问题仍有疑问,可以转至社区进行进一步交流。
Q:我们在做MMO国战类游戏,因此想咨询下资源标准。我们同屏会有70~80个玩家,这种情况下主角一般控制在多少面,多少根骨骼呢?一个Boss有80多根骨骼会有问题吗?
A:这个需要看研发团队希望在什么样的机型上运行。假设是低端机器类似红米Note2,那么建议玩家都控制在30根骨骼,1500面以下。如果只有一个怪物80根骨骼,问题并不大,但还需要考虑场景中其他物体的使用量。
建议研发团队看一下这篇文章,这是我们半年前统计的关于MMO游戏的性能数据,相信能对MMO游戏的开发团队具有借鉴意义:
此问答来自于UWA 问答社区:
如您对该问题仍有疑问,可以转至社区进行进一步交流。
Q:我们想请教一个Unity的普适性的资源管理问题。举个例子,我们现在的一个特效Prefab包含的贴图打成AssetBundle时没有单独拆分出来,就会存在一个问题,这个特效AssetBundle会存在重复加载的问题进而导致重复的特效贴图在内存中。(针对“重复加载”说明下:我们首先通过AssetBundle出来一个Object,这个Object会缓存一段时间,在这段缓存时间过后这个Object会被Destroy掉,而需要释放的特效是通过Instantiate这个Object出来的。当这个Object过了缓存时间被destroy掉后,下次需要释放相同的特效还是通过load同样的AssetBundle进行再实例化出来,这样内存中存在两份贴图了。)
A:Unity中是没有这种API来提供的,一般是团队中自行做一些资源的引用计数来进行管理。频繁调用UnloadUnusedAssets是不可取的(该函数的主要作用是查找并卸载不再使用的资源。游戏场景越复杂、资源越多,该函数的开销越大,一般在300~2000 ms范围内),但可以调用UnloadAsset来释放资源。
Q:我们游戏现在测试出来的GC是否合理?这个分配数值可以接受吗?是否存在泄露?如果存在泄露,有没有具体到每个函数的分配详情?
A:研发团队可以在测试报告中查看 ,这里有我们对于Mono堆内存的详细分析,包括堆内存具体分配 和堆内存泄露分析 两大功能,如下图所示。
就研发团队目前的数据报告来看,其堆内存分配其实是很小的,之所以有目前的堆内存调用,推测是手动调用GC的频率较高所致,研发团队可以就此再进行进一步的检测。
今天的分享就到这里。当然,生有涯而知无涯。在漫漫的开发周期中,您看到的这些问题也许都只是冰山一角,我们早已在UWA问答网站()上准备了更多的技术话题等你一起来探索和分享。欢迎热爱进步的你加入,也许你的方法恰能解别人的燃眉之急;而他山之“石”,也能攻你之“玉”。
官方技术博客:
官方问答社区:
官方技术QQ群:(仅限技术交流)
近期精彩回顾
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点}

我要回帖

更多关于 unity 创建prefab 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信