2016-12-06 10 views
0

最近、ユニティで城の戦いゲームを作っています。私はいくつかのアニメーション兵士モデルを得て、そのシーンで数百人を持つことを計画しています。問題は、モバイル上では、FPSを20未満にすることなく、一度に50を表示することはできません。私はUnityのフォーラムでこの質問をしましたが、返信はありません:(Unityでモバイルに数十から数百のアニメーションを表示するようにアニメーションを最適化する

ここにリンクがあります私が見た最も近いFIFAワールドカップモバイルでhttps://forum.unity3d.com/threads/playing-hundreds-of-animations-on-mobile.444599/

は、私がモバイル上のアニメーションの数十人でゲームを見たことがないが、それはわずか約20〜30

です:私がやったことはこれまでのところ、それらを最適化します。

あなたはアニメーションを私が持っている以上に(リンクに示されているように)最適化することは可能でしょうか?それとも、モバイルで何百ものアニメーションを持つことは不可能ですか?

あなたの知識をお寄せいただきありがとうございます!

+0

レンダリングの速度を向上させるには、ゲームに合わせてコードを最適化する必要があります。そのためには、Javaなどのコンパイル言語で最初からゲームを書く必要があります。 – Blindman67

+0

@ Blindman67 Javaでゲームを作成することは、私のことではありません。私は単純に驚いて、スキンメッシュレンダリングがモバイルでは非常に難しいことに失望していますが、私はちょっと複雑だと思います。他のプロジェクトを試してみる必要があります。 – AMintAndWin10User

+0

Geeスキンメッシュ。それは静的ポーズメッシュを使って試してみてください。スキンされたメッシュのスナップショットを取得して、アニメーション化するためにそれらを順番にレンダリングすることができるはずです。また、デバイスの限界、必要なフレームレートでの最大ポリカウント数、使用可能な空きGPU RAMの量、どこでボトルネック(GPU/CPU)があるかをテストする必要があります。その情報を知ることで、過去のものをどうやって得るのかを理解するのに役立ちます。ホームPCが2つのカラースプライトを描くのに苦労したとき、私はゲームに着手しましたが、いくつかのトリックで全軍隊がスクリーンを下って行けるようになりました。方法が常にある。 – Blindman67

答えて

0

私に物事の一般的なハングアップを与えるための@ブリンドマン67への誇り。

using System.Collections; 
using System.Collections.Generic; 
using UnityEditor; 
using UnityEngine; 

public class AnimationConverter : MonoBehaviour { 

//For example: Assets/[email protected]/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); 
     } 
    } 
} 
} 

私は私のシーンに兵士数百人を追加し、Camera.Renderはプロファイラー内のリソースのほとんどを取るので、私は自信を持ってすることができますこの方法では、Androidデバイス(一部はジャガイモよりも遅いもの)をターゲットにしているため、アニメーションがぎくしゃくするように見えます。パフォーマンスの向上は巨大なので、Camera.Renderを最適化すると、これらの文字が数百になるはずです(照明では、影など...)。

もう一度、私が実行できたアイデアのために@ Blindman67に大変感謝します。

関連する問題