So I have a freelook camera, and I want it so that it only turns when the player drags the right mouse button. The problem is, since Cinemachine is a plugin, I'm not sure what type I should set the FreeLook Camera component. I want to make something like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Cinemachine.Utility;
public class lookOnDrag : MonoBehaviour
{
// Not sure what type to set CFL
private Cinemachine CFL;
void Start()
{
CFL = GetComponent<CinemachineFreeLook>();
}
void Update()
{
if (Input.GetMouseButtonDown(1))
{
CFL.enabled = true;
}
else
{
CFL.enabled = false;
}
}
}
I've checked the documentation thoroughly and don't have an answer.
You have probably entered the above reference incorrectly and it does not recognize it correctly. using only Cinemachine and delete utility.
using Cinemachine;
Also define the variable according to the component or CinemachineVirtualCameraBase;
private CinemachineFreeLook CFL;
void Start()
{
CFL = GetComponent<CinemachineFreeLook>();
}
Related
So recently I started coding my first FPS game. I experienced a problem with my pause menu. The problem is when I have my game paused my mouse is still controling the camera and when I want to press some buttons in menu camera keeps following my mouse. I searched for solution to this problem on web, but I haven't found the solution (even my code is similar to some I've found).
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
public class PauseMenu : MonoBehaviour
{
public static bool gameIsPaused;
public GameObject pauseMenuUI;
void Update()
{
if (Input.GetKeyDown(KeyCode.Escape))
{
Pause();
}
}
public void Resume()
{
Cursor.lockState = CursorLockMode.Locked;
pauseMenuUI.SetActive(false);
Time.timeScale = 1f;
gameIsPaused = false;
}
void Pause()
{
Cursor.lockState = CursorLockMode.None;
pauseMenuUI.SetActive(true);
gameIsPaused=true;
Time.timeScale = 0f;
}
public void LoadMenu()
{
Time.timeScale = 1f;
SceneManager.LoadScene("Menu");
}
public void QuitGame()
{
Debug.Log("Quitting game...");
Application.Quit();
}
}
What I would do is to update the camera according to the pause conditon. like so:
public class CameraRotation : MonoBehaviour
{
public isGamePaused; // changed from outside when you pause/unpause the game
void Update()
{
if (isGamePaused) {
...
}
}
}
The problem with gameIsPaused (usual code convention naming to state is a bool would be isGamePaused :)) is that until you set it to true in the menu the camera will keep moving, so you may need to set the boolean to true at the time the menu pops up.
Even its not the suited case for static variables, if you want to check the pause state of your game from the camera script, you can do so like this:
public class CameraRotation : MonoBehaviour
{
public isGamePaused; // changed from outside when you pause/unpause the game
void Update()
{
if (PauseMenu.gameIsPaused) {
...
}
}
}
static stands for static in memory, so the variable value can be checked anytime from anywhere with ClassName.staticVariableName. With this I mean that as long as you set the PauseMenu.gameIsPaused variable at the times in the code where you´d like you should be able to make it work, by working I mean freeze/unfreeze the camera at the exact moment you want.
Your static PauseMenu.IsPaused is fine and a good way to do it although I usually put something like that on a GameManager class. You can find a Unity Singleton pattern online so you can start having PauseMenu.Instance.XXX so it's easy to access anything you need. That being said, you need to find the script controlling your camera and check the PauseMenu.IsPaused. Most likely you have a script attached to your camera, and all you generally need to do is find the Update() function and just do: if (PauseMenu.IsPaused) return; to stop it from working.
A new problem has just appeared in my code. In OnTriggerEnter i'm testing if the player collides with the obstacle. When I tell the script to display a message it works fine. But when I replace the Debug.Log("test"), with: deadScreen.gameObject.SetActive(true) to enable my death screen, it just dosen't work and I don't know why. Any help would be appreciated. Thanks in advance.
⠀⠀
Here's my CollisionWithObstacle script that's attached to my obstacle:⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class CollisionWithObstacle : MonoBehaviour
{
public GameObject deadScreen;
private bool isShown = false;
public static bool alive = true;
void Start()
{
isShown = false;
}
private void OnTriggerEnter(Collider other)
{
alive = false;
}
private void Update()
{
if (!alive)
{
deadScreen.SetActive(true);
deadScreen.active = true;
isShown = true;
}
}
}
Most of the time that I encountered this problem is because other scripts are interacting with the gameobject. Furthermore if it's UI you can try to use CanvasGroup and switch alpha between 0-1 and block raycasts. Let me know how it works out for you
Trying to combine these two:
https://answers.unity.com/questions/1171111/hideunhide-game-object.html
Show/ hide Unity 3D elements
I got this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Modify_Menu_Button_Handler : MonoBehaviour
{
void Start()
{
GameObject[] buttons_in_create_menu;
buttons_in_create_menu = GameObject.FindGameObjectsWithTag("CreateMenu");
}
public void ChangeMenu()
{
foreach (GameObject button in buttons_in_create_menu)
{
button.SetActive(false);
}
}
}
But, the foreach line is red-underlined, saying the buttons_in_create_menu doesn't exist in the current context.
Coming from Javascript, I'm not sure how scope works in C# and especially within Unity's game loop. Thought the Start() function would be called upon the scene loading, based on the Unity docs: link
You must define the variable globally in the class.
Like this:
public class Modify_Menu_Button_Handler : MonoBehaviour
{
public GameObject[] buttons_in_create_menu;
void Start()
{
buttons_in_create_menu = GameObject.FindGameObjectsWithTag("CreateMenu");
}
public void ChangeMenu()
{
foreach (GameObject button in buttons_in_create_menu)
{
button.SetActive(false);
}
}
}
I'm trying to make a Destroy gameobject, wait x seconds, respawn gameobject system. I have 2 scripts and I'm destorying then instantiating it again. I want to use multiples of the same prefab called "Breakable" but have only the one I'm aiming at being destroyed. Similar to games like Minecraft, aim and only the aimed at the block is destroyed.
BlockBreakItem script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class BlockBreakItem : MonoBehaviour
{
RaycastHit hit;
int layerMask = 1;
public GameObject breakableObject;
public bool isObjectDestoryed = false;
public int score = 0;
// Update is called once per frame
void Update()
{
breakableDetection();
}
void breakableDetection()
{
Ray rayLocation = Camera.main.ScreenPointToRay(Input.mousePosition);
if (Physics.Raycast(rayLocation, out hit, 1000, layerMask))
{
print("Detected");
if (Input.GetKey(KeyCode.Mouse0))
{
breakableObject = GameObject.Find("Breakable");
Destroy(breakableObject);
isObjectDestoryed = true;
score = score +1 ;
}
}
}
}
RespawnBrokenObject script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RespawnBrokenObject : MonoBehaviour
{
private BlockBreakItem BlockBreakItem;
public GameObject breakablePrefab;
// Start is called before the first frame update
void Start()
{
BlockBreakItem = GameObject.FindObjectOfType<BlockBreakItem>();
}
// Update is called once per frame
void Update()
{
if (BlockBreakItem.isObjectDestoryed == true)
{
Invoke("respawnObject", 5.0f);
BlockBreakItem.isObjectDestoryed = false;
}
}
void respawnObject()
{
GameObject tempObjName = Instantiate(breakablePrefab);
tempObjName.name = breakablePrefab.name;
BlockBreakItem.breakableObject = tempObjName;
}
}
I hope the code isn't too messy! Always worried it won't be understood xD
Fortunately it's easy and basic in Unity!
You don't do this:
breakableObject = GameObject.Find("Breakable");
The good news is the cast will tell you what object you hit! Great, eh?
It's basically:
hit.collider.gameObject
You can use hit.collider.gameObject.name in a Debug.Log for convenience.
It's that easy!
Note you then (if you need it) get your component on that object with something like .GetComponent<YourBreakishBlock>()... easy.
Note that you can CHECK if the object hit, is one of the "YourBreakishBlock" objects, by simply checking if that component is present.
Note simply google something like "unity physics raycast out hit, which object was hit ?" for endless examples,
https://forum.unity.com/threads/getting-object-hit-with-raycast.573982/
https://forum.unity.com/threads/changing-properties-of-object-hit-with-raycast.538819/
etc.
--
Make this simple class:
public class ExamplePutThisOnACube: MonoBehavior
{
public void SAYHELLO() { Debug.Log("hello!"); }
}
Now put that on SOME cubes but NOT on OTHER cubes.
In your ray code:
ExamplePutThisOnACube teste =
hit.collider.gameObject.GetComponent<ExamplePutThisOnACube>();
and then check this out:
if (teste != null) { teste.SAYHELLO(); }
Now run the app and try pointing at the various cubes!
I've been trying to use this function to trigger an sound when entering a trigger but i can't make it work. I've read and read my code and nothing seems off, looks exactly like the documentation says so i just can't figure out my error.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class footsteps_script : MonoBehaviour
{
public GameObject soundObject;
public GameObject trigger;
private AudioClip clip;
public bool nextTrig;
void Start()
{
nextTrig = false;
clip = soundObject.GetComponent<AudioClip>();
}
void OnTriggerEnter ()
{
if (Bunny_script.nextTrig == true)
{
soundObject.GetComponent<AudioSource>().PlayOneShot(clip);
nextTrig = true;
trigger.SetActive(false);
}
}
}
The AudioSource is atached to another object. The trigger is supposed to play the sound after another event happens. The trigger part works fine because nextTrig is set to true like intended, but the sound doesn't play. Also, the sound itself works fine too and with a nice volume.
it does not work because, what is this ?
clip = soundObject.GetComponent<AudioClip>();
there is no component called AudioClip.
for audio clip get it from prefabs directly to the script or if you want to get it from the audio source that you have in the soundObject, then it will be like :
clip = soundObject.GetComponent<AudioSource>().clip;
and later you will play it with PlayOneShot which will be waste of time, because you are playing the same clip which is originally taken from this audio source. which actually need just this line to play it
soundObject.GetComponent<AudioSource>().Play();
finally if you are trying to get the audio clip in the script from the prefabs your code will be like :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class footsteps_script : MonoBehaviour
{
public GameObject soundObject;
public GameObject trigger;
public AudioClip clip;
public bool nextTrig;
void Start()
{
nextTrig = false;
//don't forget to assign the your audio clip to the script from the prefabs
}
void OnTriggerEnter ()
{
if (Bunny_script.nextTrig == true)
{
if (clip =! null)
soundObject.GetComponent<AudioSource>().PlayOneShot(clip);
nextTrig = true;
trigger.SetActive(false);
}
}
}
and if you already have the audio clip in audio source which is attached to the sound object then your code will be :
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class footsteps_script : MonoBehaviour
{
public GameObject soundObject;
public GameObject trigger;
public bool nextTrig;
void Start()
{
nextTrig = false;
}
void OnTriggerEnter ()
{
if (Bunny_script.nextTrig == true)
{
soundObject.GetComponent<AudioSource>().Play();
nextTrig = true;
trigger.SetActive(false);
}
}
}