最近,我一直在努力制作一个团结的城堡战斗游戏。我已经获得了一些动画士兵模型,并计划在现场有几百个。问题是,在移动设备上,我什至无法一次显示FPS低于20。我已经在Unity的论坛上问了这个问题,没有回复:(
这是链接,因此您可以看到我到目前为止对它们进行优化的措施:https://forum.unity3d.com/threads/playing-hundreds-of-animation-animation-nimation-on-mobile.4444599/ppect>
我从未见过在移动设备上使用数十个动画的游戏。我看到的最接近的是FIFA手机,但这只有20-30。
您认为可以比我更优化动画(如链接中所示),还是不可能在移动设备上拥有数百个动画?
感谢您分享您的知识!
@blindman67的赞誉,因为我给了我一般的事物。在他的帮助下,我能够创建此脚本:
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
public class AnimationConverter : MonoBehaviour {
//For example: Assets/_@MYSTUFF/StaticAnimations/
public string SaveLocation;
//Shows progress in inspector, useful if your animation is long
public string Progress;
public Animator MyAnimator;
//anim MUST be component of this.gameObject
public Animation anim;
public SkinnedMeshRenderer SkinMeshRender;
private Mesh[] NewStaticMesh;
//length of animation clip
private float ClipLenth;
//current animator int
private int CurrentAnimatorInt;
//just to make sure we run the code in Update ONCE
private bool AllowUpdate;
//how many frames do you want to make?
public int numberOfFrames;
//time between frame captures
private float WaitAmount;
//How many frames done
public int AmountSoFar;
private void Start()
{
anim = this.gameObject.GetComponent<Animation>();
AllowUpdate = true;
}
private void Update()
{
//I'm getting an animation from my animator's current state
CurrentAnimatorInt = MyAnimator.GetInteger("SoldierState");
//checking to make sure we don't run more than once
if (AllowUpdate == true)
{
if (CurrentAnimatorInt == 1)
{
//don't run this again
AllowUpdate = false;
//the magic begins!
Debug.Log("Exporting static meshes from skinned mesh...");
ExportMeshes();
}
}
}
void ExportMeshes()
{
NewStaticMesh = new Mesh[numberOfFrames];
ClipLenth = anim.clip.length;
WaitAmount = anim.clip.length / numberOfFrames;
//now let's start waiting for the animation to play
StartCoroutine(WaitForNextMesh());
}
//IMPORTANT: We're using a coroutine because if we don't, we'll create
//the same static meshes because the animation won't change in 1 frame.
//The purpose is to wait as the animation is playing, then make a static mesh at the correct time.
IEnumerator WaitForNextMesh()
{
yield return new WaitForSeconds(WaitAmount);
AmountSoFar++;
//wait done! Let's make the static mesh!
Mesh mesh = new Mesh();
SkinMeshRender.BakeMesh(mesh);
//show progress in inspector
Progress = "Working... " + (AmountSoFar * 100 / numberOfFrames).ToString() + "%";
AssetDatabase.CreateAsset(mesh, SaveLocation + AmountSoFar.ToString() + anim.clip.name + "_StaticFromSkinned" + ".asset");
//do it again!
if (AmountSoFar < numberOfFrames)
{
//do it again, we have more meshes to make!
StartCoroutine(WaitForNextMesh());
}
else
{
//created all meshes, we're done!
Progress = "All done! :)";
//spam the console in fancy ways
Debug.Log("<color=green><b>All meshes created! You'll find them here: </b></color>" + SaveLocation);
Debug.Log("<color=red><i>Don't forget to disable/change this script, or you'll do what you just did again!</i></color>");
}
}
}
它将皮肤网眼转换为一系列静态网眼。然后,我有这个脚本可以通过那些静态网格循环以制作动画:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CharachterAnimator : MonoBehaviour {
public GameObject[] Frames;
public int CurrentFrame;
public float TimeBetweenFrames;
// Use this for initialization
void Start ()
{
StartCoroutine(GoToFrame());
}
IEnumerator GoToFrame()
{
var wait = new WaitForSeconds(TimeBetweenFrames);
while (true)
{
Frames[CurrentFrame].SetActive(true);
yield return wait;
Frames[CurrentFrame].SetActive(false);
CurrentFrame++;
if (CurrentFrame < Frames.Length)
{
Frames[CurrentFrame].SetActive(true);
}
else
{
CurrentFrame = 0;
Frames[0].SetActive(true);
}
}
}
}
我在我的场景中添加了数百名士兵。其中比土豆慢)。性能的改进是巨大的,如果我优化相机,我应该能够得到几百个角色。
再次非常感谢 @blindman67我能够执行的想法。