I really need help, when I put Invoke in C#, I have this error:
The local function 'RestartGame' is declared but never used Assembly-CSharp
I really don't know why it is happening, but here is the code:
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
Invoke("RestartGame", restartDelay);
}
void RestartGame ()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
}
}
unity manual: For better performance and maintability, use Coroutines instead.
https://docs.unity3d.com/ScriptReference/MonoBehaviour.Invoke.html
Try someting like this:
using System.Collections;
using UnityEngine;
using UnityEngine.SceneManagement;
public class GameManager : MonoBehaviour
{
bool gameHasEnded = false;
public float restartDelay = 2f;
private IEnumerator coroutine;
public void EndGame()
{
if (gameHasEnded == false)
{
gameHasEnded = true;
Debug.Log("GAME OVER");
coroutine = RestartDelayed(restartDelay);
StartCoroutine(coroutine);
}
void RestartGame()
{
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
IEnumerator RestartDelayed(float delay)
{
yield return new WaitForSeconds(delay);
RestartGame();
}
}
}
https://docs.unity3d.com/ScriptReference/MonoBehaviour.StartCoroutine.html
I upvoted flyingchris answer but just to explain your error message, I'm assuming its a yellow warning message, is that you are never calling the method RestartGame() directly anywhere in your code, you are invoking it however. Invoking is typically used for UnityEvents and coroutines are typically used for delaying a method.
Related
I'm trying to access a boolean from another script, which I using a custom namespace. The idea is to have a checkbox in the inspector per item if it should be animated or not. On a weaponmesh, I have a materialoffset animator that should trigger if that box is checked.
using MFPSEditor;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MFPS.Internal.Structures;
namespace MFPS.Addon.Customizer
{
At the bottom of this script, I have this:
[System.Serializable]
public class GlobalCamo
{
public string Name;
[SpritePreview(50)] public Texture2D Preview;
public MFPSItemUnlockability Unlockability;
public string Description;
public bool isAnimated;
public int Price
{
get => Unlockability.Price;
}
public bool animatedCamo()
{
return isAnimated;
}
public bool isFree() { return Price <= 0; }
[HideInInspector] public Sprite m_sprite = null;
public Sprite spritePreview()
{
if (m_sprite == null && Preview != null)
{
m_sprite = Sprite.Create(Preview, new Rect(0, 0, Preview.width, Preview.height), new Vector2(0.5f, 0.5f));
}
return m_sprite;
}
}
}
I am trying to access the variable "isAnimated" in the script below:
using UnityEngine;
public class MaterialOffsetAnimator : MonoBehaviour
{
// The material that will be animated
Material material;
// The speed at which the offset will be animated
public Vector2 animationSpeed;
void Update()
{
material = GetComponent<Renderer>().material;
if ( isAnimated == true )
{
// Update the material's offset based on the animation speed
material.mainTextureOffset += animationSpeed * Time.deltaTime;
}
else
{
}
}
}
isAnimated is an instance field in your GlobalCamo class, not a static field. You can't access it without a reference to an instance of GlobalCamo.
You can just make the isAnimated field static, like this:
public static bool isAnimated;
And then access it in MaterialOffsetAnimator like this:
if (GlobalCamo.isAnimated)
{
// Your code
}
Also, a side note: You don't need to use == true with booleans. If a boolean is true, the condition will evaluate to true.
Hey guys I'm learning how to create a character controller via the state pattern, which is pretty snazzy, but I'm running into this weird error
I've got a state machine pattern put together so this should be pretty straightforward and easy to handle, but it's kinda confusing. I tried freezing him in the state to see if he was transitioning from wallgrab to wallslide, but when I stop the velocity on the x and y he still slides. There's no other movement physics being applied at this time (why I'd recommend the state pattern), but for some reason his movement isn't being frozen. I can't pin a reason as to why, other than point you to my code and my github, and hope someone like my pixel art and has fun with the movement for a little bit.
All the code is in the scripts folder within the assets folder, and the states are within Assets > Scripts > Player > and then there are two folders (sub and super) The WallGrabState inherits from the PlayerTouchingWallState, and the logic is coming mainly from the WallGrabState for the physics. I'm just setting the x and y to zero, and yet he still slides, and idk what to do.
PlayerTouchingWall inherits the main state logic from playerState, and the player script loads all the states together and holds the physics and miscellaneous functions. The link to my github project is here https://github.com/roninMo/2d-Intro-Unity-Project
Here's the PlayerWallSlideState:
using UnityEngine;
public class PlayerWallSlideState : PlayerTouchingWallState
{
public PlayerWallSlideState(Player player, PlayerStateMachine stateMachine, PlayerData playerData, string currentAnimation) : base(player, stateMachine, playerData, currentAnimation)
{
}
public override void LogicUpdate()
{
base.LogicUpdate();
player.SetVelocityY(-playerData.wallslideVelocity);
// State logic
if (grabInput && input.y > 0)
{
player.StateMachine.ChangeState(player.wallGrabState);
}
}
}
And Here's the PlayerTouchingWallState:
using UnityEngine;
public class PlayerTouchingWallState : PlayerState
{
protected bool isTouchingGround;
protected bool isTouchingWall;
protected Vector2 input;
protected bool grabInput;
public PlayerTouchingWallState(Player player, PlayerStateMachine stateMachine, PlayerData playerData, string currentAnimation) : base(player, stateMachine, playerData, currentAnimation)
{
}
public override void Enter()
{
base.Enter();
}
public override void Exit()
{
base.Exit();
}
public override void LogicUpdate()
{
base.LogicUpdate();
input = player.InputHandler.RawMovementInput;
grabInput = player.InputHandler.GrabInput;
// State logic
if (isTouchingGround && !grabInput)
{
StateMachine.ChangeState(player.IdleState);
}
else if (!isTouchingWall || (input.x != player.FacingDirection && !grabInput))
{
StateMachine.ChangeState(player.InAirState);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
}
public override void DoChecks()
{
base.DoChecks();
isTouchingGround = player.CheckIfTouchingGround();
isTouchingWall = player.CheckIfTouchingWall();
}
}
The problem is that unity still applys physics to the character. I stopped it by grabbing the transform, and setting the player the position it entered in this state, along with freezing the velocity. Setting the transform is enough, but the camera was dragging upwards in place... So freezing the velocity fixed that. Anyways here's the code:
using UnityEngine;
public class PlayerWallGrabState : PlayerTouchingWallState
{
private Vector2 holdPosition;
public PlayerWallGrabState(Player player, PlayerStateMachine stateMachine, PlayerData playerData, string currentAnimation) : base(player, stateMachine, playerData, currentAnimation)
{
}
public override void Enter()
{
base.Enter();
holdPosition = player.transform.position;
HoldPosition();
}
public override void Exit()
{
base.Exit();
}
public override void LogicUpdate()
{
base.LogicUpdate();
HoldPosition();
// State logic
if (input.y > 0)
{
StateMachine.ChangeState(player.wallClimbState);
}
else if (input.y < 0 || !grabInput)
{
StateMachine.ChangeState(player.wallSlideState);
}
}
public override void PhysicsUpdate()
{
base.PhysicsUpdate();
}
public override void DoChecks()
{
base.DoChecks();
}
private void HoldPosition()
{
player.transform.position = holdPosition;
player.SetVelocityX(0f);
player.SetVelocityY(0f);
}
}
The question is very simple, I'm a beginner in unity and I'm having trouble creating two toggles for music and fx audio. At first I succeded with a simple script but the toggles encountered a NullReferenceException once the scene changed.
This is the AudioManager script:
using UnityEngine.Audio;
using System;
using UnityEngine;
using UnityEngine.UI;
[RequireComponent(typeof(Toggle))]
public class AudioManager : MonoBehaviour
{
public Sound[] sounds;
public static AudioManager instance;
private void Awake()
{
if (instance == null)
instance = this;
else
{
Destroy(gameObject);
return;
}
DontDestroyOnLoad(gameObject);
foreach (Sound s in sounds)
{
s.source = gameObject.AddComponent<AudioSource>();
s.source.clip = s.clip;
s.source.volume = s.volume;
s.source.pitch = s.pitch;
s.source.loop = s.loop;
}
}
private void Start()
{
Play("Music");
}
public void Play(string name)
{
Sound s = Array.Find(sounds, sound => sound.name == name);
s.source.Play();
}
}
do you have any suggestions about it?
Thanks in advance :)
What line is the NullReferenceException on? I don’t see anything wrong with your code as it is.
Awake doesnt work for second time.
Because it is singleton.
So you can create OnEnable method, and put that foreach to OnEnable method.
I've been working on a solution for weeks now and I think it's time to reach out. I'm trying to make a button that plays a sound when pressed by a controller, everyone will hear that sound. Using VRTK and PlayoVR, I'm able to make a non-networked version where the player can put their hand through a cube, click the trigger from the controller, and it makes a sound.
This is the code for that cube:
namespace VRTK.Examples {
using UnityEngine;
public class Whirlygig : VRTK_InteractableObject
{
public GameObject AudioSource;
public AudioSource LeftSpeaker;
public override void StartUsing(VRTK_InteractUse currentUsingObject =
null)
{
AudioSource.GetComponent<AudioSource>().Play();
}
}
}
Where I get lost is how to network it with Photon Unity Networking. This is what I have:
namespace PlayoVR
{
using UnityEngine;
using VRTK;
using UnityEngine.Video;
using NetBase;
public class PlaySync : Photon.MonoBehaviour
{
public AudioSource LeftSpeaker;
public GameObject Whirlgig;
private bool StartUsing;
// Use this for initialization
void Awake()
{
GetComponent<VRTK_InteractableObject>().InteractableObjectUsed +=
new InteractableObjectEventHandler(DoPlay);
}
void DoPlay(object sender, InteractableObjectEventArgs e)
{
StartUsing = true;
}
// Update is called once per frame
void Update()
{
// Handle firing
if (StartUsing)
{
CmdPlay();
StartUsing = false;
}
}
void CmdPlay()
{
photonView.RPC("NetPlay", PhotonTargets.All);
}
[PunRPC]
void NetPlay()
{
LeftSpeaker.Play();
}
}
}
As you can probably see, I'm a beginner. With this code, when I put my hand in the cube and press the trigger, nothing happens. If anyone can provide any help or even an alternative, I'd be very grateful.
Kind regards,
TheMusiken
I follow the tutorial write the code ,but still show this error,the script already attach to the game object
This issue caused by the Execution Order of Event Functions.
When I checked logs, OnEnable of GameUI was called before Awake of GameController.
So, GameController.instance is null when you access GameController.instance.OnGameInfoChanged in void OnEnable() in GameUI.cs.
In Unity Manual for Execution Order of Event Functions, it says Awake is before OnEnable, I guess it doesn't guarantee always.
So, I think you'd better to modify GameUI.cs like below.
public class GameUI : MonoBehaviour
{
public Text timeLabel;
private bool isInitialized = false;
void Start()
{
isInitialized = true;
GameController.instance.OnGameInfoChanged += this.OnGameInfoChanged;
}
void OnEnable()
{
if (isInitialized)
GameController.instance.OnGameInfoChanged += this.OnGameInfoChanged;
}
void OnDisable()
{
GameController.instance.OnGameInfoChanged -= this.OnGameInfoChanged;
}
void OnGameInfoChanged(GameType type)
{
//...
}
}