I have a problem. I want isOffRoad to become true whenever the wheel enters a collider attached to an object with a tag offRoadBorder, and for it to become false upon exiting it. Nothing seems to work. Both collider and the wheel have rigidbody2D attached. Thanks in advance.
public bool isOffRoad = false;
void OnTriggerEnter2D(Collider2D col)
{
Debug.Log("a");
if (col.tag == "offRoadBorder")
{
isOffRoad = true;
}
}
void OnTriggerExit2D(Collider2D col)
{
Debug.Log("b");
if (col.tag == "offRoadBorder")
{
isOffRoad = false;
}
}
Check IsTrigger field in collider componenets. Triggers are using for physically empty colliders that have script uses.
Otherwise use OnCollision2D:
void OnCollisionEnter2D(Collision2D col)
{
if (col.transform.CompareTag("offRoadBorder")) isOffRoad = true;
}
void OnCollisionExit2D(Collider2D col)
{
if (col.transform.CompareTag("offRoadBorder")) isOffRoad = false;
}
Make sure that they both have a collider and that both colliders have the "Is Trigger" enabled.
Related
I'm making a game and I want jumping to feel like jumping in Super Mario Bros. I'm able to get the result I want with a Keyboard or a Controller because they have KeyDown, Key (While pressed), and KeyUp. But touchButtons only have a single boolean. (Pressed or Not Pressed) Is there a way I can work around this?
I tried using Input.GetTouch and using the begin and end phase, this gave the correct result but I'm not sure how to implement it into a GUI button.
The code I'm using has a GUI button with a script that when the button is pressed, joybutton.Pressed = true
void PlayerJump()
{
bool canJump = charController.isGrounded;
//Button Pressed start jumpDuration
if (joybutton.Pressed && canJump)
{
isJumping = true;
jumpDuration = jumpTime;
}
if (isJumping == true)
{
if (jumpDuration > 0)
{
vertical_Velocity = jump_Force;
jumpDuration -= Time.deltaTime;
}
//timer runs out
else
{
isJumping = false;
}
}
//cancel jump if mid-air
if (!joybutton.Pressed)
{
isJumping = false;
}
}
I have no way of stopping the player from jumping as soon as they land with the GUI touchButton. I get desired results with keyboard and gamepad buttons.
Add a variable to remember the state of the button last frame. That way, you can enter the jump start block only if it's the first frame of the button being hit:
private bool wasJumpPressedLastFrame = false;
void PlayerJump()
{
bool canJump = charController.isGrounded;
//Button Pressed start jumpDuration
if (joybutton.Pressed && canJump && !wasJumpPressedLastFrame )
{
isJumping = true;
jumpDuration = jumpTime;
}
if (isJumping == true)
{
if (jumpDuration > 0)
{
vertical_Velocity = jump_Force;
jumpDuration -= Time.deltaTime;
}
//timer runs out
else
{
isJumping = false;
}
}
//cancel jump if mid-air
if (!joybutton.Pressed)
{
isJumping = false;
}
wasJumpPressedLastFrame = joyButton.Pressed;
}
So I am working on a runner game and it is almost done. The problem is that I am testing the Pause Panel and when player touches a zombie, pause panel shows up and I am restarting the game again by pressing the restart button. But when I touch the zombie again panel doesnt show up and gives me the error in the title. I am stuck and any help will be appreciated. This is the code and I referenced to the line that error sends me :
[SerializeField]
private GameObject pausePanel;
[SerializeField]
private Button RestartGameButton;
[SerializeField]
private Text ScoreText;
private int score;
void Start ()
{
pausePanel.SetActive(false);
ScoreText.text = score + "M";
StartCoroutine(CountScore());
}
IEnumerator CountScore()
{
yield return new WaitForSeconds(0.6f);
score++;
ScoreText.text = score + "M";
StartCoroutine(CountScore());
}
void OnEnable()
{
PlayerDeath.endgame += PlayerDiedEndTheGame;
}
void OnDisable()
{
PlayerDeath.endgame += PlayerDiedEndTheGame;
}
void PlayerDiedEndTheGame()
{
if (!PlayerPrefs.HasKey("Score"))
{
PlayerPrefs.SetInt("Score", 0);
}
else
{
int highscore = PlayerPrefs.GetInt("Score");
if(highscore < score)
{
PlayerPrefs.SetInt("Score", score);
}
}
pausePanel.SetActive(true); //this is the line that error sends me but I cant figure it out because I didnt try to destroy the panel in the first place.
RestartGameButton.onClick.RemoveAllListeners();
RestartGameButton.onClick.AddListener(() => RestartGame());
Time.timeScale = 0f;
}
public void PauseButton()
{
Time.timeScale = 0f;
pausePanel.SetActive(true);
RestartGameButton.onClick.RemoveAllListeners();
RestartGameButton.onClick.AddListener(() => ResumeGame());
}
public void GoToMenu()
{
Time.timeScale = 1f;
SceneManager.LoadScene("MainMenu");
}
public void ResumeGame()
{
Time.timeScale = 1f;
pausePanel.SetActive(false);
}
public void RestartGame()
{
Time.timeScale = 1f;
SceneManager.LoadScene("Gameplay");
}
I found the solution. It was a simple mistake on the OnDisable method. I deleted the += sign and changed it with -= sign because it was enabling the event when it was supposed to disable.
I'm developing in Unity, C#, and I have a bit of code that checks for player activity based on mouse position and it's working well but I'm needing to also check player activity on a touchscreen (not a mobile phone touchscreen, but a touchscreen attached to a pc). How should I modify the code that I have below to also work with touch?
private void Start()
{
InvokeRepeating("LastMousePosition", 0, _checkMousePositionTimingInterval);
}
private void Update()
{
_currentMousePosition = Input.mousePosition;
}
void LastMousePosition()
{
_prevMousePosition = Input.mousePosition;
}
void CheckPlayerIdle()
{
if (_currentMousePosition != _prevMousePosition)
UserActive = true;
else if (_currentMousePosition == _prevMousePosition)
UserActive = false;
}
Well for touch you start your inactivity timer if you don't get any touch inputs and wait for x duration.
for eg:
private void Update()
{
if(Input.touchCount == 0)
{
if(!checkingForInactivity)
{
checkingForInactivity = true;
myRoutine = StartCoroutine(CheckForInactivity());
}
}
else
{
if(checkingForInactivity) StopCoroutine(myRoutine);
}
}
Ienumrable CheckForInactivity()
{
yield new waitForSecond(3.0f);
//user is inactive
}
}
I am doing a tutorial from VR Dev School. The lesson is Picking Up an Object and Parent the Transform. This is the code I copied exactly from the lesson. I have the script and a sphere collider attached to controlller(left). I've tried toggling 'is trigger' on/off. The collision is not being detected in the console. I am not receiving any errors or warnings.
Any assistance is appreciated and I will answer any questions
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(SteamVR_TrackedObject))]
public class PickupParent : MonoBehaviour {
SteamVR_TrackedObject trackedObj;
SteamVR_Controller.Device device;
void Awake () {
trackedObj = GetComponent<SteamVR_TrackedObject>();
}
void FixedUpdate () {
device = SteamVR_Controller.Input((int)trackedObj.index);
if(device.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You are holding 'Touch' on the trigger");
}
if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You activated touchdown on the trigger");
}
if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You activated TouchUp on the trigger");
}
if (device.GetPress(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You are holding 'Press' on the trigger");
}
if (device.GetPressDown(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You activated press down on the trigger");
}
if (device.GetPressUp(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You activated press Up on the trigger");
}
}
void onTriggerStay(Collider col)
{
Debug.Log("You have collided with " + col.name + " and activated onTriggerStay");
if (device.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
{
Debug.Log("You have collided with " + col.name + " while holding down Touch");
col.attachedRigidbody.isKinematic = true;
col.gameObject.transform.SetParent(gameObject.transform);
}
}
}
This is a simple mistake. It should be OnTriggerStay not onTriggerStay. Please capitalize the O and trigger/collision should be detected.
I almost have a working radio, where the player can walk up to it, press a button and cycle through songs. Everything works except for that with each button press the new song will play but the original will continue to play underneath it. For each new song that is played a new object is created but they are all called 'One Shot Audio,' so I don't know how to destroy them. If I can fix this bug then this should be a useful radio script for anyone who wants to use it.
Update, here is my modified radio code, now working, with the help of the answer below:
void OnTriggerEnter2D(Collider2D target) {
if (target.gameObject.tag == "radio") {
radioEnter = true;
}
}
void OnTriggerExit2D(Collider2D target) {
if (target.gameObject.tag == "radio") {
radioEnter = false;
}
}
public void radioUse(){
if ((Input.GetKeyDown (KeyCode.M)) && song3on == true && radioEnter == true) {
TurnOn ();
song1on = true;
song2on = false;
song3on = false;
}
else if ((Input.GetKeyDown (KeyCode.M)) && song1on == true && radioEnter == true) {
TurnOff ();
song1on = false;
song2on = true;
song3on = false;
TurnOn();
}
else if ((Input.GetKeyDown (KeyCode.M)) && song2on == true && radioEnter == true) {
TurnOff ();
song1on = false;
song2on = false;
song3on = true;
TurnOn ();
}
}
public void Update() {
raidoUse();
}
Since PlayClipAtPoint does not return an AudioSource to manage you should not use it for these kind of sounds. I recommend setting up your radio with one AudioSource and multiple AudioClips in a array. Just drag the clips you want to the inspector and use the public methods to control the radio. This way you can reuse it with different songs.
The following code is not tested.
Public class Radio : MonoBehaviour
{
AudioSource output;
public AudioClip[] songs;
int songIndex = 0;
void Start(){
output = gameObject.AddComponent<AudioSource>();
}
public void ToggleSong(){
songIndex++;
output.clip = songs[songIndex % songs.Length];
output.Play();
}
public void TurnOn(){
ToggleSong();
}
public void TurnOff(){
output.Stop();
}