How to use Profiler to profile a Start() function in Unity - unity3d

When I useProfiler.BeginSample("Update Example") and Profiler.EndSample() in Update(), I can see "Update Example" in Update.ScriptRunBehaviorUpdate in the profiler window.
But when I use Profiler..."Start Example"... in Start(), I cannot see or find any mention in the profiler. Is there any way to track code in Start()?
using UnityEngine;
using UnityEngine.Profiling;
public class Example : MonoBehaviour
{
BoxParameter bParameter;
// Start is called before the first frame update
void Start()
{
Profiler.BeginSample("Start Example");
bParameter = GameObject.Find("Main Camera").GetComponent<ZombieInventory>().box;
Debug.Log(bParameter.width);
Profiler.EndSample();
}
// Update is called once per frame
void Update()
{
Profiler.BeginSample("Update Example");
bParameter = GameObject.Find("Main Camera").GetComponent<ZombieInventory>().box;
Debug.Log(bParameter.width);
Profiler.EndSample();
}

Play with Clear on Play and Deep Profile turned on.
Moves to 1Frame after playback. It is easier to step using a controller.
Then you can check the following.
To see if you get a value, try searching for the script name in the search window. It will not give you the details, but you can check if the value is taken.
The following test code was used.
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Profiling;
public class ProfilingTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
Profiler.BeginSample("Start Example");
var list = new List<int>();
for (var i = 0; i < 2000000; ++i)
{
list.Add(i);
}
Profiler.EndSample();
}
// Update is called once per frame
void Update()
{
Profiler.BeginSample("Update Example");
var list = new List<int>();
for (var i = 0; i < 2000000; ++i)
{
list.Add(i);
}
Profiler.EndSample();
}
}
BTW: Maybe it is because it is test code, but the Find function is heavy and should not be used. caching Camera.main is the fastest way. the same goes for GetComponent.
Camera _camera;
void Start()
{
_camera = Camera.main;
}

Related

Unity Microphone.Start() lag, how to get rid of it?

Using unity 2020.3 and the XR Plug-in (currently only oculus but will be moving to openxr i hope) and trying to start the microphone when secondary button is pushed. It works but starting the microphone causes lag. Coroutine doens't help, I tried threading which stops the lag but then can't do anything with the audioclip. This has been asked a few times over the years but no answer yet. Here's the code:
void Update()
{
foreach(var d in devices){
if (d.TryGetFeatureValue(CommonUsages.secondaryButton, out isPressed)){
if (isPressed && !wasTalking)
{
wasTalking = true;
asource.PlayOneShot(walkietalkie);
//start_recording = new Thread(startRecording);
//start_recording.Start();
startRecording();
}
else if (wasTalking && !isPressed){
finishRecording();
wasTalking = false;
}
}
private void startRecording(){
recording = Microphone.Start(null, false, 30, freq);
startRecordingTime = Time.time;
yield return null;
}
Edit: I've removed the useless coroutine. Why the -1 to my question?
The primary way I reckon that you could alleviate the stutter is moving this work to another thread, which is notoriously hard with Unity.
A solution to this could be using or adapting another method of recording audio like NAudio.
Use coroutines.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Threading;
public class TestMic : MonoBehaviour
{
[SerializeField] AudioSource self;
public int samplerate = 44100;
public int time = 10;
// Start is called before the first frame update
void Start()
{
//Debug.Log(Microphone.devices);
StartCoroutine("test");
}
IEnumerator test()
{
self.clip = Microphone.Start(null, true, time, samplerate);
self.loop = true;
self.Play();
yield return null;
}
// Update is called once per frame
void Update()
{
}
}

load Scene with Script but it turns Black

I've done it so far that when my player dies the level is restarted and I've written everything in the script but when I try it and the scene is reloaded everything is somehow extremely dark compared to before, although all settings from the camera etc. are the same and I don't know if I'm doing something wrong or if it's a bug
my Script:
public class GameManager : MonoBehaviour
{
public GameObject enemyPrefab;
// Start is called before the first frame update
void Start()
{
GameObject player = GameObject.Find("Player");
SpawnEnemy();
}
// Update is called once per frame
void Update()
{
RestartGame();
}
void RestartGame()
{
if(GameObject.Find("Player").GetComponent<PlayerMovement>().playerHealth <= 0)
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
You need to bake your lighting inside your scene. Here are instructions on how:
Head to Window > Rendering > Lighting
Press Generate Lighting (Make sure Auto Generate is unselected)
Source
Your code has some trouble. But I'm not going to fix rotation issues. But here your working sample:
public class GameManager : MonoBehaviour {
public GameObject enemyPrefab;
// Start is called before the first frame update
void Start()
{
GameObject player = GameObject.Find("Player");
SpawnEnemy();
}
// Update is called once per frame
void Update()
{
RestartGame();
}
bool navigated = false;
void RestartGame()
{
if (!navigated)
{
if(GameObject.Find("Player").GetComponent<PlayerMovement>().playerHealth <= 0)
{
navigated = true;
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
}

Display 10 separate Meshes one by one with looping behavior to create "Animation" for empty GameObject?

I have 10 meshes that are each basically freeze-"frames" of an animation of a whale swimming.
If I were to loop through displaying these meshes then it would create a pseudo-animation, which is what I want.
How can this be achieved? Currently I have GameObject AnimTest, and I've placed the 10 mesh .obj files as children to it. I've started with this code on a script changeMeshes for the GameObject:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class changeMeshes : MonoBehaviour
{
//Create array of the meshes
public float[] currentMesh;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
for (int i = 0; i < 10; i++)
{
currentMesh[i].gameObject.GetComponent<MeshRenderer>().enabled = true;
}
}
}
This is obviously very wrong since I'm new and confused, so I'm getting errors with script like float does not contain a definition for gameObject. Can anyone help lead me down the correct path?
Edit: Here's my better try at it.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class changeMeshes : MonoBehaviour
{
//Create array of the meshes
public GameObject[] whaleMeshes;
void FindWhales()
{
whaleMeshes = GameObject.FindGameObjectsWithTag("WhaleMesh");
print(whaleMeshes.Length);
}
void CycleWhales()
{
for (int i = 0; i < whaleMeshes.Length; i++)
{
if (i > 0)
{
whaleMeshes[i - 1].gameObject.GetComponentInChildren<MeshRenderer>().enabled = false;
}
whaleMeshes[i].gameObject.GetComponentInChildren<MeshRenderer>().enabled = true;
}
}
// Start is called before the first frame update
void Start()
{
FindWhales();
}
// Update is called once per frame
void Update()
{
CycleWhales();
}
}
The result now is that only the last Mesh is permanently rendered, rather than the script cycling through the meshes on a loop. How do I get the meshes to loop?
Well .. a float has no property .gameObject .. not even Mesh would
Since you say the objects are children of this component you can simply iterate through them.
And then I would simply activate and deactivate the entire GameObject.
Sounds like what you would want to do is something like
public class changeMeshes : MonoBehaviour
{
// How long should one mesh be visible before switching to the next one
[SerializeField] private float timePerMesh = 0.2f;
public UnityEvent whenDone;
private IEnumerator Start()
{
// Get amount of direct children of this object
var childCount = transform.childCount;
// Get the first child
var currentChild = transform.GetChild(0);
// Iterate through all direct children
foreach(Transform child in transform)
{
// Set all objects except the first child to inactive
child.gameObject.SetActive(child == currentChild);
}
// Iterate though the rest of direct children
for(var i = 1; i < childCount; i++)
{
// Wait for timePerMesh seconds
yield return new WaitForSeconds(timePerMesh);
// Set the current child to inactive
currentChild.gameObject.SetActive(false);
// Get the next child
currentChild = transform.GetChild(i);
// Set this one to active
currentChild.gameObject.SetActive(true);
}
// Optionally do something when done like e.g. destroy this GameObject etc
yield return new WaitForSeconds(timePerMesh);
whenDone.Invoke();
}
}

Unity 2D - How to place obstacle in Running game?

I finish making running game. But I placed obstacle like this :
This way makes phone frozen often. So I make a prefeb is made of obstacle object like this :
I want to use function SetActive(bool) to appear/disappear obstacle. Finally, How it works is My runner is at a standstill and background, obstacle, coin, juwel is moved. But My creator script has a big problem.
My Prolem :
As you see, This code create blank(red box) between two obstacle prefebs. I can't find problem. Plz help me...
Creator Script :
using UnityEngine;
using System.Collections;
public class CsPartCreator : MonoBehaviour {
int count = 1;
float timer = 0.0f;
// Use this for initialization
void Start () {
for (int i = 1; i < 26; i++)//set Deactive all object excluding first object (Because This object is watched at first.)
transform.GetChild(i).gameObject.SetActive(false);
}
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if (timer > 5f && count < 23)//every 5 seconds and count is smaller than the number of prefeb
{
transform.GetChild(count).gameObject.SetActive(true);//
count++;
timer = 0;
}
}
}
This is my Hierarchy :
I think , That missing prefab's Z value is more negative than background , Or you have used a sorting layer which is set to be behind background.
And Check if all obstacle gameobjects correctly orderered in Hirachy Part0, Part1, Part2, Part3 like that. Let me know if those are in correct order
Please check that :)
using UnityEngine;
using System.Collections;
using System.Linq;
using System.Collections.Generic;
public class CsPartCreator : MonoBehaviour
{
private GameObject player;
float timer = 0.0f;
private List<GameObject> obstacles;
void Awake()
{
player = GameObject.FindWithTag("Player");
obstacles = new List<GameObject>();
}
// Use this for initialization
void Start()
{
for (int i = 0; i < 26; i++)//set Deactive all object excluding first object (Because This object is watched at first.)
{
obstacles.Add(transform.GetChild(i).gameObject);
transform.GetChild(i).gameObject.SetActive(false);
}
}
// Update is called once per frame
void Update()
{
if (obstacles == null || obstacles.Count() == 0)
return;
var toActivate = obstacles.Where(x => x.transform.position.x > transform.position.x && x.transform.position.x < transform.position.x + 10).ToList(); // +10 is the range
foreach (GameObject go in toActivate)
{
go.SetActive(true);
obstacles.Remove(go);
}
}
}
Set player gameobject to "Player" tag as in image below

Sorting Order Not Working Correctly

I am trying to change the order of a sorting layer in unity for a 2D game but the below script isn't working for me:
using UnityEngine;
using System.Collections;
public class LevelManager : MonoBehaviour {
public GameObject player;
public SpriteRenderer deadGuy;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (player.transform.position.y < deadGuy.transform.position.y)
{
deadGuy.sortingOrder = 0;
} else
{
deadGuy.sortingOrder = 2;
}
}
}
The objects have been linked in the inspector window unity before running the game.
EDIT
This is now my code:
using UnityEngine;
using System.Collections;
public class LevelManager : MonoBehaviour {
public GameObject player;
public GameObject deadGuy;
public bool belowTheY;
// Use this for initialization
void Start () {
deadGuy.GetComponent<SpriteRenderer>().sortingOrder = 2;
}
// Update is called once per frame
void Update () {
if (player.transform.localPosition.y < deadGuy.transform.localPosition.y)
{
belowTheY = true;
deadGuy.GetComponent<SpriteRenderer>().sortingOrder = 0;
} else
{
belowTheY = false;
deadGuy.GetComponent<SpriteRenderer>().sortingOrder = 2;
}
}
}
bekowTheY is activating if the user goes below deadGuy's Y position so I know the if statement is executing correctly. However the sorting layer is not being changed
It seems that the player object was on sorting order 0 also, so when the deadGuy object was scripted to go to sorting order 0, it was still showing in front due to taking precedence.