I want to destroy or remove a spawning prefab from my scene when the mouse clicks on the gameobject. I'm trying to use the code below from the Unity docs, however I'm presented with the following error:
object reference not set to the instance of an object.
This script is attached to my main camera. onclick crashes the game. Can anyone see where this is going wrong?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickDestroy : MonoBehaviour
{
public GameObject destroyCube;
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit(); //*
if (Physics.Raycast(ray, out hit)) //**
{
print("true" + hit.point);
}
}
}
}
Solution 1
Make sure your Camera is really tagged as MainCamera
if not click there and select MainCamera from the list
Solution 2
Get and check the main camera at game start
priavte Camera _camera;
privtae void Awake()
{
_camera = Camera.main;
if(!_camera)
{
Debug.LogError("No Camera tagged MainCamera in Scene!");
enabled = false;
}
}
Solution 3
Or instead of using Camera.main at all instead get the Camera component directly
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class onClickDestroy : MonoBehaviour
{
public GameObject destroyCube;
privtae Camera _camera;
private void Awake()
{
_camera = GetComponent<Camera>();
}
// Update is called once per frame
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Ray ray = _camera.ScreenPointToRay(Input.mousePosition);
RaycastHit hit = new RaycastHit();
if (Physics.Raycast(ray, out hit))
{
print("true" + hit.point);
}
}
}
}
Related
how to reproduce a sound effect while loading a scene?
I would like to play a sound effect when moving to the next scene, but it does not play. I already tried with method DontDestroyOnLoad but it doesn't work and I get this error: NullReferenceException: Object reference not set to an instance of an object
LevelLoader.LoadNextLevel ()
this is my script to manage sounds:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SoundManagerScript : MonoBehaviour
{
public static AudioClip clikSound, shootSound;
static AudioSource audioScr;
// Start is called before the first frame update
void Start()
{
clikSound = Resources.Load<AudioClip> ("clik");
shootSound = Resources.Load<AudioClip>("shoot");
audioScr = GetComponent<AudioSource> ();
}
// Update is called once per frame
void Update()
{
}
public static void PlaySound(string clip)
{
switch (clip)
{
case "clik":
audioScr.PlayOneShot(clikSound);
break;
case "shoot":
audioScr.PlayOneShot(shootSound);
break;
}
}
}
and this is the script for switching between scenes:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
public Animator transition;
public float transitionTime = 1f;
static AudioSource audioScr;
public void LoadNextLevel()
{
DontDestroyOnLoad(audioScr.gameObject);
SoundManagerScript.PlaySound("shoot");
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1));
}
IEnumerator LoadLevel(int LevelIndex)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(LevelIndex);
}
}
Becasuse you're required gameobjects are destroyed. AudioSource by itself not enough. Maybe your AudioListener destroyed?
To arrange those things. I recommend you to have multiple scenes. in example, Persistent scene, MenuScene, Level1 etc, and you can put your audios in Persistent scene.
You can have more than one scene via SceneManager.LoadScene("OtherSceneName", LoadSceneMode.Additive);. That's where multiple scenes gets it's power.
It may be hard but i recommend you to use Addressables for handling scenes and assets like audios.
How to turn off scene transition animations?
I would like to disable the animation ONLY for the RestartGame command. so that the animation works for other commands.
Is there any script for such a thing?
this is my animation script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class LevelLoader : MonoBehaviour
{
public Animator transition;
public float transitionTime = 1f;
public void LoadNextLevel()
{
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1));
}
public AudioClip impact;
IEnumerator LoadLevel(int LevelIndex)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
SceneManager.LoadScene(LevelIndex);
yield return new WaitForSeconds(0.3f);
AudioSource.PlayClipAtPoint(impact, transform.position);
}
}
and this is my RestartGame command which is in another script:
public void RestartGame()
{
SceneManager.LoadScene(PlayerPrefs.GetInt("SavedScene"));
}
In your actualy code, the RestartGame method don't use de animation, but if you have an animation on your scene when this starts, you can save a PlayerPref variable inside the RestartGame method before load the scene, and then check the variable before the animation.
For example:
public void RestartGame()
{
PlayerPrefs.SetInt("isRestarting",1);
SceneManager.LoadScene(PlayerPrefs.GetInt("SavedScene"));
}
then in the start of the new scene
void Start ()
{
if(PlayerPrefs.GetInt("isRestarting",0)!=1)
{
//Do the animation
}
}
You can add another option to IEnumerator that controls the animation.
IEnumerator LoadLevel(int LevelInde, bool hasAnimation = true)
{
if (hasAnimation)
{
transition.SetTrigger("Start");
yield return new WaitForSeconds(transitionTime);
}
SceneManager.LoadScene(LevelIndex);
yield return new WaitForSeconds(0.3f);
AudioSource.PlayClipAtPoint(impact, transform.position);
}
Now set it to true when restart and false to other cases. On LoadNextLevel:
StartCoroutine(LoadLevel(SceneManager.GetActiveScene().buildIndex + 1, false));
I am new to unity, and trying something like below, but I can either move only in one direction, or not moving at all.
My cube is a trigger, and is not using gravity. I have checked the Kitematic box. I am trying to make the cube move to and fro, so that player have difficuly collecting it.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using UnityEngine;
public class movedanger : MonoBehaviour
{
private int mytime = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
MyMover(mytime);
}
void MyMover(int mytime)
{
if (mytime <= 3)
{
transform.Translate(Vector3.forward * Time.deltaTime);
mytime++;
}
else
{
transform.Translate(-Vector3.forward * Time.deltaTime);
mytime = 1;
}
}
}
What you are looking for is to and fro movement of an object. You can achieve this with Mathf.PingPong() function instead of using translate. I have tested it with a cube, you can set the minimum and maximum distance it should move to and the speed at which it travels. Since you want the cube to move 3 seconds in one direction at a time. You can calculate the speed as distance/time so the max distance it should travel to from the current distance and the time (3 seconds) it takes. Hope this helps.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MoveCube : MonoBehaviour {
public float min = 2f;
public float max = 8f;
public float SpeedOfMovement = 2f;
// Start is called before the first frame update
void Start () {
}
// Update is called once per frame
void Update () {
transform.position = new Vector3 (Mathf.PingPong (Time.time * SpeedOfMovement, max - min) + min, transform.position.y, transform.position.z);
}
}
With InvokeRepeating you will call the same MoveCube method every 3 seconds.
using UnityEngine;
public class MoveDanger: MonoBehaviour
{
public bool isForward = false;
private void Start()
{
InvokeRepeating("MoveCube", 0f, 3f);
}
private void MoveCube()
{
if (isForward)
{
transform.Translate(Vector3.back);
isForward = false;
}
else
{
transform.Translate(Vector3.forward);
isForward = true;
}
}
}
Honestly the best and easiest way to do something like this, once you get used to it, is just to
Use Unity's incredibly simple animator system:
(Essentially just click "new animation" and then drag the object around as you want it animated.)
There are 100s of tutorials online explaining how to use it.
It's one of those things where once you use it and see how easy it is, you will do a "facepalm" and never bother again with other ways.
It's really "the Unity way" to achieve the goal here, dead easy and flexible.
I have a cube in my scene so what I want is to drag and drop a 2d UI image of wrench tool over the cube and as soon as I drop that image on 3d cube the wrench prefab must be instantiated there.
Here is an image showing what I need
I am using below code to drag my UI Image around the scene but dont know how to drop this on 3D Cube and instantiate a wrench prefab
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wrench : MonoBehaviour {
public bool Dragging = false;
public bool collision = false;
Vector3 position;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
public void BeginDrag(){
position = gameObject.transform.position;
Dragging = true;
}
public void Drag(){
transform.position = Input.mousePosition;
}
public void Drop(){
if (!collision) {
gameObject.transform.position = position;
}
Dragging = false;
}
}
usually on stack overflow you should add some information about what you did and show some code so we can help figure out what is the problem in your approach. People won't write all the code for you without knowing what your project currently look like.
That being said, if you don't have anything to show yet and just wonder where to start, here are an idea:
You can get the position of the mouse in the world, and shoot a ray from it. Then check if this ray hits and object. like this:
if (Input.GetMouseButtonUp(0))
{
ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(ray, out hit))
{
Debug.Log(hit); // Find a way to figure out what object you hit
}
}
I want to make that on keyboard r button press reset object into position: x112 y8 z153. Object name is Sphere i can rename it.
And i want a gui slider that can change forceadder 50f in game from 0 to 500.
I am a beginner. Just finished begginer tutorials. What code do i need to get? i tried to make that reset button my self but dosent do anything to me it says in debug that its pressed but it dosent reset it. Soo i removed that code.
My code right now:
using UnityEngine;
using System.Collections;
public class ShootMeBall : MonoBehaviour
{
public float forceadder = 500f;
void OnMouseDown()
{
rigidbody.AddForce (transform.forward * forceadder);
rigidbody.useGravity = true;
}
void Awake()
{
Debug.Log ("I am awake.");
Screen.lockCursor = true;
gameObject.renderer.material.color = Color.yellow;
}
}
Here's the solution(You will need to drag the object you're moving into the scripts GameObject variable in the inspector, and the slider into the slider slot):
using UnityEngine;
using UnityEngine.UI;
using System;
public class Example : MonoBehavior
{
public GameObject go;
public Slider slider;
private float force;
void Update()
{
if(Input.GetKeyDown(KeyCode.R))
{
go.transform.position = new Vector3(112f, 8f, 153f);
}
force = (float)slider.value;
}
}
Don't forget to set the min/max values of the slider, and the value "Use whole numbers" to true if it matters.