Ground Plane Stage rotate child object - c#

In my project I have a Ground Plane Stage with an child object. Now I want to rotate this object with a UI Button. If i hold the button down it should rotate and if I release the button the rotation should stop. Unfortunately I´m not able to do this.
This is my script:
public class RotateObject : MonoBehaviour
{
public float rotationSpeed = 45f;
public bool isPressed = false;
public void TogglePressed(bool value)
{
isPressed = !isPressed;
} //edit added missing Brace
void Update()
{
if (isPressed)
{
transform.Rotate(Vector3.up * rotationSpeed * Time.deltaTime);
}
}
}
I added Event Trigger with Pointer Down and Pointer Up to the button.
The script is attached to my gameObject and the TogglePressedfunction is linked to Pointer Down with the checkbox checked and to Pointer Up, here checkbox is not checked.
If I test it in Unity and click the button, the inspector shows that it works, but if I upload it to my phone, there is no rotation of the object.
EDIT:
Input.GetMouseButtonDown()
void Update()
{
if (isPressed && Input.GetMouseButtonDown(0))
{
// Same Code
}
}
Input.GetButtonDown()
void Update()
{
if(isPressed && Input.GetButtonDown("Fire1"))
{
//Same Code
}
}
EDIT2:
This is my script i use now:
public class RoatateObject : MonoBehaviour
{
public float rotationSpeed = 45f;
void Update()
{
if(Input.GetMouseButtonDown(0))
{
transform.Rotate(Vector3.up * rotationSpeed * Time.deltaTime);
}
}
}

i dont know exactly if pointerdown is recognized on phones, do you have tried Input.GetMouseButtonDown() (also trigger on phones)?
maybe to speed up your testing try unity remote to test local instead of uploading to your phone

Related

Press any key to play

I'm new to unity, and I'm trying to build a menu to a game, but I can't seem to be able to use a key press to activate the button.
public class MenuCamControl : MonoBehaviour
{
public Transform currentMount;
public float speed = 0.1f;
public float zoom = 0.1f;
void Update()
{
transform.position = Vector3.Lerp(transform.position, currentMount.position, speed);
transform.rotation = Quaternion.Slerp(transform.rotation, currentMount.rotation, speed);
}
public void SetMount(Transform newMonut)
{
currentMount = newMonut;
}
}
Edit: I added the code I have right now, which is a animation.
Edit2: This is where the animation leads image
Use Input.anyKey and a flag to determine when the first key is pressed to not trigger it multiple times.
public class Example: MonoBehaviour
{
private bool keyPressed = false;
void Update()
{
if (Input.anyKey && !keyPressed)
{
keyPressed = true;
}
else
{
// put your camera move code here
}
}
}
This method also picks up any mouse input as well. If you truly just want any keyboard input and not any mouse input to continue I can update my answer.
You do not need a UI button for this. Just a function to track if an input occurs and another to handle starting or loading your game. If you want the game to start when a button is clicked, you would just need to assign the onClick listener to a function either in code or in the inspector.
If you add what code you'd like to run or what you'd like to do after the click I can update my snippet.
Edit: Here is how you would combine my snippet and your current code. You can also use a Coroutine, but it is not needed.
public class MenuCamControl : MonoBehaviour
{
public Transform currentMount;
public float speed = 0.1f;
public float zoom = 0.1f;
private bool keyPressed = false;
void Update()
{
if (Input.anyKey && !keyPressed)
{
keyPressed = true;
}
else
{
transform.position = Vector3.Lerp(transform.position, currentMount.position, speed);
transform.rotation = Quaternion.Slerp(transform.rotation, currentMount.rotation, speed);
}
}
// I am not sure what this does, it currently is not called?
public void SetMount(Transform newMonut)
{
currentMount = newMonut;
}
}
With a Coroutine, it could look something like
void Update()
{
if (Input.anyKey && !keyPressed)
{
keyPressed = true;
if(referenceToCoroutine == null)
referenceToCoroutine = StartCoroutine(DoCameraAnimation());
}
}
private IEnumerator DoCameraAnimation()
{
...
}
You would need to change your current camera animation slightly to work in a Coroutine.

FixedUpdate slightly fired up even if scene is paused with Time.timeScale = 0f

I'm a newbie in unity & c# . The FixedUpdate function does some Rigidbody action (here pushing the cube over the z axis)
However the scene works fine in development (cube starts at z = 0 )
The problem is in build , the cube starts at certain distance means z = 5 or 6
According to my understanding , I believe this is caused due to FixedUpdate being fired for some milli seconds before it notice Time.timeScale = 0f in PauseGame function
And when it notice this it behave as expected.
But then on Restart function when being called up (called by a button) using SceneManager.LoadScene function cube starts with z= 0 in build.
clip at development and clip with bug at build
where did I go wrong, thanks in advance.
image of bug at build, cube starts at certain position
image of development which working fine as expected cube starts at z = 0
public class GameController : MonoBehaviour
{
public GameObject tapToStart;
private void Start()
{
tapToStart.SetActive(true);
PauseGame();
}
private void Update()
{
StartGame();
}
public void Restart()
{
SceneManager.LoadScene("Game");
}
public void PauseGame()
{
Time.timeScale = 0f;
}
public void StartGame()
{
tapToStart.SetActive(false);
Time.timeScale = 1f;
}
}
public class PlayerScript : MonoBehaviour
{
public new Rigidbody rigidbody;
public float force;
private void Update(){}
private void FixedUpdate()
{
rigidbody.AddForce(0, 0, force * Time.deltaTime);
}
}
You are correct! FixedUpdate is called at relatively'fixed' intervals. It doesn't matter if something is done in your other code and you need it to get updated immediately. FixedUpdate will just keep pressing on at a a regular interval.
You can verify your suspicions by placing the line:
rigidbody.AddForce(0, 0, force * Time.deltaTime);
Inside your Update() function.
Now, onto the solution. I suggest that create place the following code in your currently empty Update() function:
if(Time.timeScale = 0f){
rigidbody.velocity = Vector3.zero;
rigidbody.angularVelocity = Vector3.zero;
}
Now, as soon as you press the pause button, it will be detected on the next frame of Update() and the object will be frozen. This will likely occur even before FixedUpdate is called. Of course, if you want to 'restore' the velocity and angular velocity when you unpause, you will need to store that data, and then set it back up when you unpause the game.
The issue has been solved .. I can't pause on start,
need to create a Boolean in PlayerScript.
public class PlayerScript : MonoBehaviour
{
public new Rigidbody rigidbody;
public float force;
public bool isGameStart; // this Boolean
private void Update(){}
private void FixedUpdate()
{
if (isGameStart)
{
rigidbody.AddForce(0, 0, force * Time.deltaTime);
}
}
}
and using that bool value , we need to use rigidbody component.
and in StartGame function in GameController we must assign true to that bool value
public class GameController : MonoBehaviour
{
public GameObject tapToStart;
public PlayerScript playerScript;
private void Start()
{
tapToStart.SetActive(true);
PauseGame();
}
private void Update()
{
StartGame();
}
public void Restart()
{
SceneManager.LoadScene("Game");
}
public void PauseGame()
{
Time.timeScale = 0f;
}
public void StartGame()
{
tapToStart.SetActive(false);
Time.timeScale = 1f;
playerScript.isGameStart = true;
}
}
this worked for me , this solution was given by a Youtuber "Unity city".. credits to him.

Building a camera transition for switching rooms

I'm trying to create a Zelda type camera that changes position after you reach a trigger point.
this is the code for the camera movement
public class CameraMovement : MonoBehaviour {
public Transform target;
public float smoothing;
public Vector2 maxPosition;
public Vector2 minPosition;
void LateUpdate()
{
if (transform.position != target.position)
{
Vector3 targetPosition = new Vector3(target.position.x, target.position.y, transform.position.z);
targetPosition.x = Mathf.Clamp(targetPosition.x, minPosition.x, maxPosition.x);
targetPosition.y = Mathf.Clamp(targetPosition.y, minPosition.y, maxPosition.y);
transform.position = Vector3.Lerp(transform.position, targetPosition, smoothing);
}
}
}
and this is the code for the room transition
public class RoomMove : MonoBehaviour
{
public Vector2 cameraChange;
public Vector3 playerChange;
private CameraMovement cam;
// Start is called before the first frame update
void Start()
{
cam = Camera.main.GetComponent<CameraMovement> ();
}
// Update is called once per frame
void Update()
{
}
private void OnTriggerEnter2D(Collider2D other)
{
if(other.CompareTag("Player"))
{
cam.minPosition += cameraChange;
cam.maxPosition += cameraChange;
other.transform.position += playerChange;
}
}
}
I've already tried to look up the answer in google and I found something similar but it did not work for me.
This is a little difficult due to the lack of details, info, and desire.
First make sure your setup is correct.
Does the object with RoomMove on it have a 2D collider marked trigger?
Does player have the "Player" tag on it?
Does the main camera have the movement script with the target variable set to the instance of the player? (Not a prefab, from the hierarchy)
Double check all of these first.
What you have here leads me to believe that all of your levels are side by side in one scene correct?
You could try removing the clamping and simply give each room an empty transform in the middle and when you hit the transition change the camera's target.

Unity raycast possible bug?

this is my code for raycast in my school project game. If I put script on object everything is working just fine. But if I close Unity and reopen my project, the value of "jakDaleko" = distance stays locked on 1129.395 instead of changing every frame.
What should I change so it will work everytime and not just the first time ipress play button.
Here's my code.
script 1 = raycast
public class SmerDivani : MonoBehaviour {
public static float VzdalenostOdCile;
public float VzdalenostOdCileInterni;
// Update is called once per frame
void Update() {
RaycastHit Hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out Hit)) {
VzdalenostOdCileInterni = Hit.distance;
VzdalenostOdCile = VzdalenostOdCileInterni;
}
}
}
Second script
public class TabuleMesto1 : MonoBehaviour
{
public float JakDaleko;
public GameObject AkceTlacitko;
public GameObject AkceText;
public GameObject UIQuest;
public GameObject ThePlayer;
public GameObject NoticeCam;
void Update() {
JakDaleko = SmerDivani.VzdalenostOdCile;
}
void OnMouseOver() {
if (JakDaleko <= 5) {
AkceTlacitko.SetActive(true);
AkceText.SetActive(true);
}
if (JakDaleko > 5)
{
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
}
if (Input.GetButtonDown("Akce")) {
if (JakDaleko <= 5) {
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
UIQuest.SetActive(true);
NoticeCam.SetActive(true);
ThePlayer.SetActive(false);
}
}
}
void OnMouseExit() {
AkceTlacitko.SetActive(false);
AkceText.SetActive(false);
}
}
I'm not quite sure what you're trying to achieve? Maybe this should "fix" your problem, you're not clearing the distance if the raycast don't hits....
void Update() {
RaycastHit Hit;
if (Physics.Raycast(transform.position, transform.forward, out Hit)) {
VzdalenostOdCileInterni = Hit.distance;
}
else {
VzdalenostOdCileInterni = 0.0f;
}
VzdalenostOdCile = VzdalenostOdCileInterni;
}
Additionally I think you should use transform.forward instead of transform.TransformDirection(Vector3.forward)
I think that the biggest problem was the name of the file. For some reason, my stupidity included, the solution was to rename the script from table1 to table_1

How to apply a knockback without it looking like teleportation?

So I have the following script which applies force when a player gets hit. I like the speed that the knockback is currently set to, but I would like for the player to move back more smoothly (as in you can see the object slide back) instead of him instantly moving back. Here is the script:
public class meleeAttack : MonoBehaviour
{
int speed = 1000;
void Start()
{
}
void Update()
{
}
void OnTriggerStay(Collider other)
{
if (other.gameObject.tag == "Player" && Input.GetKeyUp(KeyCode.F))
{
other.GetComponent<Rigidbody>().AddForce(transform.forward * speed);
}
}
}
What would be the best approach to achieving this?

Categories

Resources