Unity walking sounds (if and buttons error) - c#

Basically, I need a script to play a walking-sound while my player is walking and a running-sound while he's running. Due to how my player is setup it needs to be done with the Input and Keys...
I have this basic script made but it doesn't work too well. The transition from running -> walking -> stop and running -> stop and so on doesn't work consistently or even well. The other problem is pressing shift while standing still also plays the sound. I already tried doing the SHIFT && W || W && SHIFT and it just doesn't work.
Any help would be much appreciated!!
My Foley.cs script:
using UnityEngine;
using System.Collections;
public class Foley : MonoBehaviour {
public AudioClip Footsteps;
public AudioClip RunningSound;
// Update is called once per frame
void Update () {
if (Input.GetKeyDown(KeyCode.LeftShift) && !audio.isPlaying)
{
audio.clip = RunningSound;
audio.loop = true;
audio.Play();
} else if (Input.GetKey(KeyCode.W) && !audio.isPlaying && !Input.GetKey(KeyCode.LeftShift)) {
audio.clip = Footsteps;
audio.loop = true;
audio.Play();
}
if (Input.GetKeyUp(KeyCode.W) && audio.isPlaying)
{
audio.Stop();
}
if (Input.GetKeyUp(KeyCode.LeftShift) && audio.isPlaying)
{
if (Input.GetKey(KeyCode.W))
{
audio.clip = Footsteps;
audio.loop = true;
audio.Play();
} else {
audio.Stop();
}
}
}
}

This script should do basically what you want. On 'w' play walk sound, on w + shift, play run sound.
#pragma strict
var walk : AudioClip;
var run : AudioClip;
var isWalking : boolean = false;
var isRunning : boolean = false;
function Update()
{
GetState();
PlayAudio();
}
function GetState()
{
if ( Input.GetKey(KeyCode.W))
{
if ( Input.GetKey( "left shift" ) || Input.GetKey( "right shift" ) )
{
// Running
isWalking = false;
isRunning = true;
}
else
{
// Walking
isWalking = true;
isRunning = false;
}
}
else
{
// Stopped
isWalking = false;
isRunning = false;
}
}
function PlayAudio()
{
if ( isWalking )
{
if ( audio.clip != walk )
{
audio.Stop();
audio.clip = walk;
}
if ( !audio.isPlaying )
{
audio.Play();
}
}
else if ( isRunning )
{
if ( audio.clip != run )
{
audio.Stop();
audio.clip = run;
}
if ( !audio.isPlaying )
{
audio.Play();
}
}
else
{
audio.Stop();
}
}

Related

How to disable Prefabs in Unity 2D?

Im working on an 2d local multiplayer platformer Game. In the game are obstacles (Spikes), when the player collides with them the player will die. I want the Players of the game to decide if they would like to enable or disable the Spikes (the link leads to an image that will help understanding my problem)by pressing a Key. I already wrote a script for that and added it to my dontdestroyOnLoad GameManager. So all my spikes I built are the same Prefabs. My idea was to disable the main Prefab from the Project folder to disable all the spikes in every scene, until you press a Key to reactivate them again. The Problem is, that only the texture itself in the Project Panel disables and not the Spikes Prefabs in the Hierarchy, because the prefabs turn into regular gameObjects. How can I fix this?
My Script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//using System.Threading;
public class DisableSpikes : MonoBehaviour
{
[Header("Spikes")]
public KeyCode disableSpikes;
public float time;
public GameObject prefabSpikes;
public bool toggleSpikes = true;
[Header("Player Green")]
public KeyCode disableGreen;
public GameObject prefabGreen;
public bool toggleGreen = true;
[Header("Reset Score")]
public KeyCode resetScore;
// Start is called before the first frame update
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == true)
{
prefabSpikes.SetActive(false);
Debug.Log("Disable");
//Thread.Sleep(1000);
Invoke("SetFalse", time);
}
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == false)
{
prefabSpikes.SetActive(true);
Debug.Log("Anable");
//Thread.Sleep(1000);
Invoke("SetTrue", time);
}
if (Input.GetKeyDown(disableGreen) && toggleGreen == true)
{
prefabGreen.SetActive(false);
Debug.Log("Disable");
//Thread.Sleep(1000);
Invoke("SetFalse", time);
}
if (Input.GetKeyDown(disableGreen) && toggleGreen == false)
{
prefabGreen.SetActive(true);
Debug.Log("Anable");
//Thread.Sleep(1000);
Invoke("SetTrue", time);
}
if (Input.GetKeyDown(resetScore))
{
ScoreScriptBlue.scoreValueBlue = 0;
ScoreScriptRed.scoreValueRed = 0;
ScoreScriptGreen.scoreValueGreen = 0;
RoundScript.scoreValueRound = 0;
TimeScript.scoreValueTime = 0;
}
}
public void SetFalse()
{
toggleGreen = false;
toggleSpikes = false;
}
public void SetTrue()
{
toggleGreen = true;
toggleSpikes = true;
}
}
void Update() {
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == true){
// show
// renderer.enabled = true;
gameObject.GetComponent<Renderer>().enabled = true;
}
if (Input.GetKeyDown(disableSpikes) && toggleSpikes == false) {
// hide
// renderer.enabled = false;
gameObject.GetComponent<Renderer>().enabled = false;
}
}

Same trigger enter tag, but two different actions

I have troubles trying to make two different actions on trigger enter, its same name tag so I have no idea how to do it. For example I have ground button which has function, etc on first trigger enter it is disabling rotation of some other object, on second trigger enter it enables rotation back.Tried with bools but its not working well, Im thinking about int, but Im not sure. Thanks for any help, Im new in coding.
Heres the code;
if (other.gameObject.CompareTag("Player"))
{
var buttonRenderer = button.GetComponent<Renderer>();
buttonRenderer.material.SetColor("_Color", Color.red);
Rotationplane.isRotated = false;
}
EDIT:
#derHugoDont know mate, lost my mind...but finally I managed to do it over the if statements, I have no idea does it effect the performance. Heres code if someone has the same problem. Opening the bottle of whiskey...done for today.
private void FixedUpdate()
{
if(firstCollisionDone == true)
{
firstCollisionAavaliable = false;
secondCollisionAvaliable = true;
}
if(secondCollisionDone == true)
{
secondCollisionAvaliable = false;
firstCollisionAavaliable = true;
}
}
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
if(firstCollisionAavaliable == true)
{
var buttonRenderer = button.GetComponent<Renderer>();
buttonRenderer.material.SetColor("_Color", Color.red);
Rotationplane.isRotated = false;
firstCollision = true;
}
if(secondCollisionAvaliable == true)
{
var buttonRenderer = button.GetComponent<Renderer>();
buttonRenderer.material.SetColor("_Color", Color.white);
Rotationplane.isRotated = true;
secondCollision = true;
}
}
}
private void OnTriggerExit(Collider other)
{
if (other.gameObject.CompareTag("Player"))
{
if(firstCollision == true)
{
firstCollisionDone = true;
firstCollision = false;
firstCollisionAavaliable = false;
secondCollisionDone = false;
}
if(secondCollision == true)
{
secondCollisionDone = true;
secondCollision = false;
secondCollisionAvaliable = false;
firstCollisionDone = false;
}
}
}
}```
I assume the flag you want to change is the Rotationplane.isRotated.
You could simply invert it's state like e.g.
if (other.gameObject.CompareTag("Player"))
{
var buttonRenderer = button.GetComponent<Renderer>();
buttonRenderer.material.SetColor("_Color", Color.red);
Rotationplane.isRotated = !Rotationplane.isRotated;
}

Game objects scaling up when transform.parent set to null

I'm working on a small game where objects are put in a boat, then a key press makes the boat "sail".
To move all the objects that are standing on the boat, i am setting the parent of each object to an empty guide object in the boat then changing the position of the boat. (I have also tried parenting the objects into the boat object itself)
The following is a script applied to the boat object.
variables set in the BoatScript class:
public class BoatScript : MonoBehaviour {
public List<string> boatList;
public KeyCode interact;
public GameObject tempObject;
public string whichSide;
public string direction;
public bool canSail;
}
Start and Update method:
void Start () {
canSail = false;
whichSide = "start";
direction = "toFinish";
speed = 0f;
}
void Update () {
if (canSail == true)
{
SetSail();
}
if (boatList.Contains("FARMER") && whichSide == "start" && Input.GetKeyDown(interact))
{
speed = 0.5f;
CharacterCheck();
}
else if (boatList.Contains("FARMER") && whichSide == "finish" && Input.GetKeyDown(interact))
{
speed = -0.05f;
CharacterCheck();
}
}
Here are my OnTrigger methods:
void OnTriggerEnter(Collider other)
{
Debug.Log(other.gameObject.name + " collided with " + gameObject.name);
promptText.text = "";
if(CheckValidObject(other.gameObject.name) == true) {
boatList.Add(other.gameObject.name);
logBox.text = logBox.text + "\nThe " + other.gameObject.name + " is in the boat";
}
if (other.gameObject.name == "FARMER")
{
promptText2.text = "Press E to set sail";
}
}
void OnTriggerExit(Collider other)
{
boatList.Remove(other.gameObject.name);
logBox.text = logBox.text + "\nThe " + other.gameObject.name + " has left the boat";
promptText.text = "";
if (other.gameObject.name == "FARMER")
{
promptText2.text = "";
}
}
Setting sail:
void SetSail()
{
promptText.text = "";
promptText2.text = "";
addParents();
if (whichSide == "sailing" && direction == "toFinish")
{
speed = 0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "sailing" && direction == "toStart")
{
speed = -0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "start" || whichSide == "finish")
{
gameObject.transform.Translate(speed, 0, 0);
removeParents();
}
}
void addParents()
{
foreach(string o in boatList)
{
GameObject obj = GameObject.Find(o);
obj.GetComponent<Rigidbody>().useGravity = false;
obj.GetComponent<Rigidbody>().isKinematic = true;
if (obj.name == "FARMER") { obj.transform.parent = playerGuide.transform; }
else {obj.transform.parent = itemGuide.transform; }
}
}
void removeParents()
{
foreach (string o in boatList)
{
GameObject obj = GameObject.Find(o);
obj.GetComponent<Rigidbody>().useGravity = true;
if(obj.name != "FARMER") {obj.GetComponent<Rigidbody>().isKinematic = false; }
obj.transform.parent = null;
}
}
The problem: Once the boat reaches and hits the collider for the other side, the boat stops as expected but the objects that were just removed from the parent begin to scale up continuously like this:
e.g 1 https://i.gyazo.com/d35ae729757b8e71c25fd1b4a3857dae.mp4
e.g 2 https://i.gyazo.com/80637919bfd114a42d187300b7faef25.mp4
I'm not too sure what is causing this. Any help is much appreciated, thank you.
Instead of setting the parent via transform.parent, use transform.SetParent(targetTransform, false);. The second, bool, parameter determines if the game object's transform will maintain it's position, orientation, and scale. By setting it to false, the transform will maintain it's current values, while setting it to true will modify the position, orientation, and scale to maintain the world position. You can check this for further info transform.SetParent
Are youu sure it is scaling up and not moving up in the Z axes? From what im looking it is going towards the camera but not scaling up. You should debug the position and scale in the update method to see whats really happening there.
Below comment: "Well then you will have to debug it more carefully, i would first try, setting canSail to false as soon as it reaches the end. Perhaps the method addParent which is always being executed is wrong, what does the object itemGuide does? edit: i just seen the second video, from my perspective that seems gravity, what you meant with problems with scaling up is because its moving out from the boat?"
Solution:
void SetSail()
{
promptText.text = "";
promptText2.text = "";
addParents();
if (whichSide == "sailing" && direction == "toFinish")
{
speed = 0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "sailing" && direction == "toStart")
{
speed = -0.05f;
gameObject.transform.Translate(speed, 0, 0);
}
else if (whichSide == "start" || whichSide == "finish")
{
gameObject.transform.Translate(speed, 0, 0);
canSail = false; //Adding this line solves the issues, must have been affecting transform properties to child objects.
removeParents();
}
}

Why Line renderer in unity not updating?

I am trying to draw a line from camera to a instantiated object.I am using the scene UnityARHitTest Example.When I touch on a vertical plane the object gets instantiated and i want to draw a line from camera to the object.When I move my device the line should show from the centre of my camera.For some reason line renderer is not showing when I call it in the Late update.
LineRenderer lins;
public GameObject Lineprefab;
bool HitTestWithResultType (ARPoint point, ARHitTestResultType resultTypes)
{
List<ARHitTestResult> hitResults = UnityARSessionNativeInterface.GetARSessionNativeInterface ().HitTest (point, resultTypes);
if (hitResults.Count > 0 && check==true)
{
foreach (var hitResult in hitResults)
{
Debug.Log ("Got hit!");
if (Select == 0)
{
Debug.Log("hit-zero!");
Instantiate(Instaobj[0], ForSelect);
check = false;
}
if (Select == 1)
{
Debug.Log("hit-one!");
Instantiate(Instaobj[1], ForSelect);
check = false;
}
if (Select == 2)
{
Debug.Log("hit-two!");
Instantiate(Instaobj[2], ForSelect);
check = false;
}
if (Select == 3)
{
Debug.Log("hit-three!");
Instantiate(Instaobj[3], ForSelect);
check = false;
}
if (Select == 4)
{
Debug.Log("hit-four!");
Instantiate(Instaobj[4], ForSelect);
check = false;
}
if (Select == 5)
{
Debug.Log("hit-five!");
Instantiate(Instaobj[5], ForSelect);
check = false;
}
m_HitTransform.position = UnityARMatrixOps.GetPosition (hitResult.worldTransform);
m_HitTransform.rotation = UnityARMatrixOps.GetRotation (hitResult.worldTransform);
Debug.Log (string.Format ("x:{0:0.######} y:{1:0.######} z:{2:0.######}", m_HitTransform.position.x, m_HitTransform.position.y, m_HitTransform.position.z));
obj.StopPlaneTracking();
if (GameObject.Find("debugPlanePrefab(Clone)"))
GameObject.Find("debugPlanePrefab(Clone)").SetActive(false);
else
Debug.Log("no prefab");
//lins.SetPosition(0, m_HitTransform.position);
//lins.SetPosition(1, obj.m_camera.transform.position);
return true;
}
}
return false;
}
When I use lins.setposition() in the above method(which is commented) a line is shown in the output.When I use lins.setposition() in the below LateUpdate() the output is not shown nothing comes.
private void Start()
{
spawngenerator();
}
void spawngenerator()
{
GameObject newline = Instantiate(Lineprefab);
lins = newline.GetComponent<LineRenderer>();
//lins.SetPosition(0, m_HitTransform.position);
//lins.SetPosition(1, obj.m_camera.transform.position);
}
private void LateUpdate()
{
lins.SetPosition(0,obj.m_camera.transform.position );
lins.SetPosition(1,m_HitTransform.position );
}

When I run a script which is attached to my canvas to pop up a pause menu it only runs once

I attached a script to my canvas called PauseMenu which runs once and pauses initially and resumes but never pauses again when clicking escape. Here is my code:
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif
using RTS;
public class PauseMenu : MonoBehaviour {
Canvas canvas;
private Player player;
public Button Button2;
void Start()
{
Debug.Log ("asdf");
player = transform.root.GetComponent< Player >();
canvas = GetComponent<Canvas>();
canvas.enabled = false;
ResourceManager.MenuOpen = false;
Button2.GetComponent<Button>().onClick.AddListener(() => { Resume();});
}
void Update()
{
Debug.Log ("Jake");
if(Input.GetKeyDown(KeyCode.Escape) && ResourceManager.MenuOpen == false) Pause();
//Button2.GetComponent<Button>().onClick.AddListener(() => { Resume();});
//if(Input.GetKeyDown(KeyCode.Escape)) Pause();
//if(Input.GetKeyDown(KeyCode.Escape) && ResourceManager.MenuOpen == true) Resume();
}
public void Pause()
{
//if(Event.current.type == KeyCode.Escape)Debug.Log ("as12d12f2");
//if(Event.current.type == EventType.KeyDown)Debug.Log ("as12d12f2");
Debug.Log ("asdf2");
canvas.enabled = true;
Time.timeScale = 0.0f;
if(player) player.GetComponent< UserInput >().enabled = false;
//canvas.enabled = !canvas.enabled;
//Time.timeScale = Time.timeScale == 0 ? 1 : 0;
//ResourceManager.MenuOpen = true;
}
public void ResumePublic(){
Resume ();
}
private void Resume() {
Debug.Log ("asdf1");
Time.timeScale = 1.0f;
GetComponent< PauseMenu >().enabled = false;
if(player) player.GetComponent< UserInput >().enabled = true;
Cursor.visible = false;
canvas.enabled = false;
//Screen.showCursor = false;
//GetComponent<UserInput > ().enabled = true;
Debug.Log ("a2323sdf1");
ResourceManager.MenuOpen = false;
Button2.GetComponent<Button>().onClick.AddListener(() => { Resume();});
}
public void Quit()
{
#if UNITY_EDITOR
EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
}
What is happening is that this is attached to the parent object canvas which has the child object panel which has child objects button1,2and3 . And when the user presses escape the menu should pop up, pause time(which it does) and resume when either the resume button is clicked (button2) or escape is pressed however this only works once and the code no longer runs (ie the update procedure is no longer running) - please can someone help me fix this issue.
In your Resume() you set the PauseMenu Component to false
GetComponent< PauseMenu >().enabled = false;
But you did nothing to turn back that component in your pause function. So the script get disable after the first toggle and is never running again.
Could this be the problem?

Categories