How do I use SteamVR_LoadLevel to fade between scenes in unity3d? - unity3d

I've got this at the top,
public GameObject mainCamera
and then I've got this within an if statement,
SteamVR_LoadLevel tempload = mainCamera.GetComponent<SteamVR_LoadLevel>();
tempload.fadeOutTime = 1f;
tempload.fadeInTime = 1f;
tempload.Trigger();
but I'm getting this error when triggering the if statement,
Coroutine 'LoadLevel' couldn't be started because the the game object 'Camera (head)' is inactive!
Edit 1. I figured it out, I should have made the mainCamera variable of type SteamVR_Camera and I should have nullchecked it as well as tested for it being active and enabled.

Check state game object "Camera (head)" in hierarchy window and active him

Related

Get the object or renderer displayed (rendered on top)

Is it possible to know I a mesh renderer is not visible due to the fact its being occluded by another gameObject? Up to what I researched, Rederer.isVisible responds to "isRendered" and scene params needs to be baked. So I wonder if there could be a simple way to know if an scene element is rendered on top of other in a simple manner. Larger explanation below.
Consider a simplified use case, with a camera (with occlusion culling activated), an occluder and an occludee such as this:
With the shadows options disabled (for both occluder and occludee. I would think disabling this is only needed for the ocludee but disabled for both just in case):
And a simple script to check visibility options:
using UnityEngine;
public class RenderCheck : MonoBehaviour
{
MeshRenderer mr;
private void Start()
{
mr = GetComponent<MeshRenderer>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space)) {
bool isVisible = mr.isVisible;
Debug.Log($"cube visible: {isVisible}");
}
}
void OnBecameVisible() {
Debug.LogError($"{this.GetHashCode()} VISIBLE!!");
}
void OnWillRenderObject() {
Debug.LogError($"{this.GetHashCode()} VISIBLE!!");
}
}
The result I expected is that the ocludee .isVisible would return false, and that OnWillRenderObject() would be executed constantly after OnBecameVisible() is executed on the event of the occludee been moved out the occluders back, so into the sight of the camera. However I get .isVisible = true and the log thrown by the OnWillRenderObject().
I am aware of the fact that the Scene view cameras will also cause this value to be true. The explained outcome considers no scene camera and only the gamePlay camera (with occlusion culling activated).
I got this approach to work baking the scene occlusion options following the documentation steps. But my question here more if its rendered or not regarding the oclussion settings, is to know if a gameobject or a mesh is rendered "on top" of other (in the case of culling not being applied). Unity needs to handle that as it is how the render takes place in the scene.
There seem to be a bunch of useful options here for what I am after, however, for .isVisible to work I need to set and bake the occusion scene options (afaik). So .isVisible responds more to "isRendered"
fact. According to the documentation shouldn't Renderer.isVisible be giving the result I expected in a direct/simple manner and not be influenced by the fact of being rendered or not by dynamic occlusion?
Edit: As far as I checked, seems that only a raycast can address blocking by geometry. All these other things mean "visible" in the sense that the camera's rendering pipeline has to consider the object in some way.
With a raycast I can get the "physical" block, determined by a collision. Isn't there any way to determine the "graphical" block? As I said, that is figured out somewhere soas to be renedered accordingly in the display screen, so is that info available somehow?

Unity: OnCollisionEnter fires only on NEW entry, but not on NEW entry on different object with same name

I am building a platformer with appearing boxes. The box gets rendered as soon as the player hits it hitbox. This works just fine like so:
public class AppearingBoxes : MonoBehaviour
{
public GameObject Block, RageFace;
bool showBlock = false;
void Start()
{
showBlock = false;
}
void OnCollisionEnter(Collision2D col)
{
if (col.gameObject.name == "Birdy")
{
showBlock = true;
}
}
void FixedUpdate()
{
Block.GetComponent<Renderer>().enabled = showBlock;
RageFace.GetComponent<Renderer>().enabled = showBlock;
}
}
This script is attached to all of those boxes. Each box is an individual box but all with the same script and properties and name:
But here comes the issue. Only the first HIT triggers a box. As you can imagine, the player jumps on top of those invisble boxes and then triggers the one he hits. The player now moves forward over the other boxes that are still invisble and enters there hitboxes. However they dont appear. I believe this is due to the fact that the player is still in the "same" hitbox even though it is a different prefab object. If I jump ontop of the invisible platform and then fall back down to it (i left and then reentered the trigger) the box on which I land immeadiately appears as it should.
So what can I do to get the box to appear as soon as the player touched it even though he is has not left the hitbox of the box before?
Thank you! :)
Try to change the boxes colliders to isTrigger and use instead OnTriggerEnter2D
Or maybe it's because you use OnCollisionEnter instead of OnCollisionEnter2D ?
There is a problem in your code. I don't know if you missed that or it is a typo but you can not use OnCollisionEnter with a Collision2D parameter. Your game would run but it must be giving you this error message:
Script error: OnCollisionEnter
This message parameter has to be of type: Collision
The message will be ignored.
Use OnCollisionEnter2D instead
void OnCollisionEnter2D(Collision2D col)
{
if (col.gameObject.name == "Birdy")
{
showBlock = true;
}
}
Everyone, I did find a "workaround" It sill doesnt really explain the issue but alreast works...
What I did was to increase the size of the BoxCollider for every box just a little bit more. Like 3 pixels bigger than the actual box the player stands on. This solved the issue but makes me wonder: If the player didnt "really" collide with the collider in the first place he wouldve fallen through. But he didnt. Now the colliders a slightly bigger and everything gets triggered just perfect. Maybe a bug in the engine?
Thanks for all your help
He didn't fall because the collider isn't Trigger that's all.

How to stop NavMeshAgent separating from Animator?

I am working on a research project that uses a NavMeshAgent. I currently have a very simple scene where an agent is spawn at the start, walks through an "entrance" trigger collider, an "exit" trigger collider, then ultimately collides with a "destroyer" trigger collider with a script that ends the scene. Nothing complex, no physics collisions should be occurring.
I've been running some simulations both in the editor and in -batchmode -nographics via an executable that logs a basic runtime statistic when the scene ends. I found that in both the Unity editor and the CLI execution that occasionally the scene's execution time would spike. I finally caught what was happening in action- the NavMeshAgent component was becoming detached from my agent and floating out in front of it.
In this picture you can see the two colliders on the agent (one very small through his body for physics and one larger one for his "personal space",) the exit trigger collider (the giant red box on the right,) and floating between the two is a capsule-shaped NavMeshAgent component.
I used this unity page detailing how to use NavMeshAgents with animators, but after recreating their recommended setup, I am still having the issue.
Does anyone have any solutions for anchoring the NavMeshAgent to the agent itself?
I met exactly the same problem, where making the NavMeshAgent component a child and setting the NavMeshAgent's local position in every frame solved the problem.
private NavMeshAgent agent;
void Awake()
{
agent = gameObject.GetComponentInChildren<NavMeshAgent>();
anim = gameObject.GetComponent<Animator> ();
}
private void Update()
{
agent.transform.localPosition = Vector3.zero;
// todo:
// set animator
}
void OnAnimatorMove ()
{
// Update position to agent position
transform.position = agent.nextPosition;
}
For those of you who stumbled here, but for whom the accepted answer did not work. Make sure that navMeshAgent.updatePosition is set to true or that it is not changed within a script. This could be the cause of the separation.
NavMeshAgent navMeshAgent;
// This may cause the agent to separate
navMeshAgent.updatePosition = false;
// This will make sure it is synced
navMeshAgent.updatePosition = true;
This works as of version 2022.1 of the Unity API. Here are the docs for the function : https://docs.unity3d.com/ScriptReference/AI.NavMeshAgent-updatePosition.html

Add particles on button click in unity

I am new to unity 3d, I have to do some enhancement in exiting project.. if user choose correct option then I have to show some particles around the button at runtime.
My code for adding particles is below ..not working:
ParticleSystem ps = GetComponent<ParticleSystem>();
ps.Play ();
I have also added particles component from unity editor..
Thanks in advance
Edit :
as #kardux suggested:
declaration :
[SerializeField] private ParticleSystem ps;
on method :
ps.Play()
Screenshot from inspector:
Error:
I/Unity (23313): NullReferenceException
I/Unity (23313): at UnityEngine.ParticleSystem.<Play>m__0 (UnityEngine.ParticleSystem ps) [0x00001] in /Users/builduser/buildslave/unity/build/artifacts/generated/common/modules/ParticleSystem/ParticleSystemBindings.gen.cs:3666
I/Unity (23313): at UnityEngine.ParticleSystem.IterateParticleSystems (Boolean recurse, UnityEngine.IteratorDelegate func) [0x00003] in /Users/builduser/buildslave/unity/build/artifacts/generated/common/modules/ParticleSystem/ParticleSystemBindings.gen.cs:3780
I/Unity (23313): at UnityEngine.ParticleSystem.Play (Boolean withChildren) [0x00020] in /Users/builduser/buildslave/unity/build/artifacts/generated/common/modules/ParticleSystem/ParticleSystemBindings.gen.cs:3666
I/Unity (23313): at UnityEngine.ParticleSystem.Play () [0x00005] in /Users/builduser/buildslave/unity/build/artifacts/generated/common/modules/ParticleSystem/ParticleSystemBindings.gen.cs:3661
First of all if you're using particles inside Unity UI I highly advise you looking to UIParticleSystem.cs script from Unity UI Extension repository: this is a community gathering of many useful UI tools :)
(simply don't forget to add the UI/Particles/Hidden shader that you can find here)
You can change the sprite you want to use here:
Also keep in mind when using this script that you will have to scale your particles according to your screen (particles are initialized at a size of 1 because that's 1 meter in Unity 3D world: but now you will probably be in canvas space which will be something like 1920x1080px so 1px will be very small). You can find some base settings below:
Now coming to your scrip I suspect you simply have to call Stop() before Play() like this (note I used a burst emission type in my particle system settings):
ParticleSystem ps = GetComponent<ParticleSystem>();
ps.Stop ();
ps.Play ();
P.-S. Please note that if you use UIParticleSystem script you will have to consider your particles system as an UI item (will be rendered on top of other items based on hierarchy order)
Hope this helps,
EDIT:
You have two ways of setting up your GameObjects:
you have all component on the same GameObject (ParticleSystem, UIParticleSystem and YOUR_SCRIPT): this way you can get the ParticleSystem reference by calling GetComponent<ParticleSystem>() inside your script
you have one particle GameObject (with ParticleSystem and UIParticleSystem) and YOUR_SCRIPT is on another GameObject: you can't call GetComponent<ParticleSystem>() in your script since it will search on the components of this GameObject so you declare a ParticleSystem ps; variable (either public or [SerializeField] private) that you assign through the Inspector by dragging your particle GameObject to it.
Note that implicitly, GetComponent<ParticleSystem>() equals this.gameObject.GetComponent<ParticleSystem>(): that's why it will search components from the current GameObject.
EDIT 2:
Not sure why your script throw this NullReference exception: I just tried with a very short script and it works perfectly...
public class TestScript: MonoBehaviour
{
[SerializeField]
private ParticleSystem ps;
void Start()
{
// This one is not even needed
ps.Stop();
}
public void PlayParticles()
{
ps.Stop();
ps.Play();
}
}
Provided you have a particle system on the same gameObject as the script that is calling it, it should be fine.
Are you using a UI button? If so, have a look here..
http://answers.unity3d.com/questions/852397/particle-system-in-46-ui.html
It's old but still relevant.
Are you using the New Unity UI System or GUI, Is the UI worldspace?
Create a empty gameobject - attach the particle to that.
Whenever you want emit particles call Gameobject.SetActive(true);
Make sure Play on Awake option is checked in the particle system.
Set the position of the particle according to your UI.
public GameObject particle;
//include the particle in the gameobject
void Start() {
particle.SetActive(false);
}
void button() {
particle.SetActive(true);
}
//this works.

Unity. Cant play animation in animator

i'm making a game in 2d and whenever i create an animation sprite, an animator controller is created automatically, i dont know why, i once tried it but i thought it wouldnt be necesary for animations i just want to make in 2d.. so after trying many times to play an animation without the animator (because unity says i have to set the animation legacy, which i dont know where), i gave it a try to play animations in the animator.. i searched through the script reference and wrote the code just like this:
#pragma strict
var velocity : float = 8;
function Update ()
{
var movement = Input.GetAxis("Horizontal") * velocity;
transform.Translate(Vector2.right * movement * Time.deltaTime);
if(Input.anyKey)
Animator.Play("move");
}
the error that unity says is : Assets/PlayerControl.js(12,26): BCE0020: An instance of type 'UnityEngine.Animator' is required to access non static member 'Play'.
so i tried to do this:
function Start ()
{
//var anim = GetComponent("Animator");
}
function Update ()
{
var movement = Input.GetAxis("Horizontal") * velocity;
transform.Translate(Vector2.right * movement * Time.deltaTime);
if(Input.anyKey)
anim.Play("move");
}
and another error occurs: Assets/PlayerControl.js(17,17): BCE0005: Unknown identifier: 'anim'.
i just want to play one simple animation that will just change the sprites. i know how to play animations without the animator.. so please tell me what to do with it.. how to stop unity auto creating animator controller or set the animation legacy, or how to fix this problem with the animator script.
Update:
i removed the code code just to make other stuff while i search solution for this but now it seems that animator is running this animation no matter what.. i made another state on it as idle, but then it goes to the animation i created.. i really dont understand this.
You can check Unity3D Animation mechanism with example http://docs.unity3d.com/Manual/Animator.html
Unity doesn't give us static method for animation play. See above.
http://docs.unity3d.com/ScriptReference/Animator.html
Try to play of animation
GetComponent("Animator").Play("move", -1, 0.0f);
Check the script reference of official site.
http://docs.unity3d.com/ScriptReference/Animator.Play.html