Control object rotation by mouse click in unity - unity3d

I need help with my project in unity
I want to stop each object by clicking on it.
What I did so far:
all my objects rotate but when I click anywhere they all stop, I need them to stop only if I click on each one.
This is my code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EarthScript : MonoBehaviour
{
public bool rotateObject = true;
public GameObject MyCenter;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
if(rotateObject == true)
{
rotateObject = false;
}
else
{
rotateObject = true;
}
}
if(rotateObject == true)
{
Vector3 axisofRotation = new Vector3(0,1,0);
transform.RotateAround(MyCenter.transform.position,axisofRotation, 30*Time.deltaTime);
transform.Rotate(0,Time.deltaTime*30,0,Space.Self);
}
}
}

Theres two good ways to achieve this. Both ways require you to have a collider attatched to your object.
One is to raycast from the camera, through the cursor, into the scene, to check which object is currently under the cursor.
The second way is using unity's EventSystem. You will need to attach a PhysicsRaycaster on your camera, but then you get callbacks from the event system which simplifies detection (it is handled by Unity so there is less to write)
using UnityEngine;
using UnityEngine.EventSystems;
public class myClass: MonoBehaviour, IPointerClickHandler
{
public GameObject MyCenter;
public void OnPointerClick (PointerEventData e)
{
rotateObject=!rotateObject;
}
void Update()
{
if(rotateObject == true)
{
Vector3 axisofRotation = new Vector3(0,1,0);
transform.RotateAround(MyCenter.transform.position,axisofRotation, 30*Time.deltaTime);
transform.Rotate(0,Time.deltaTime*30,0,Space.Self);
}
}

Related

How to destroy instantiated button upon collision exit - Unity 3D

I am a beginner in Unity and I am currently making a simple game. I have a problem where the instantiated Button is not destroyed.
The process of the script is to instantiate a button and destroy it upon collision exit. But when I move out of the object, the object stays and it is not destroyed. i don't know if there is something wrong with the Destroy code of line.
Here is the script for the collision:
using UnityEngine;
using UnityEngine.UI;
public class InteractButtonPosition : MonoBehaviour
{
public Button UI;
private Button uiUse;
private Vector3 offset = new Vector3(0, 0.5f, 0);
// Start is called before the first frame update
void Start()
{
//uiUse = Instantiate(UI, FindObjectOfType<Canvas>().transform).GetComponent<Button>();
}
// Update is called once per frame
void Update()
{
//uiUse.transform.position = Camera.main.WorldToScreenPoint(this.transform.position + offset);
}
private void OnCollisionEnter(Collision collisionInfo)
{
if(collisionInfo.collider.name == "Player")
{
uiUse = Instantiate(UI, FindObjectOfType<Canvas>().transform).GetComponent<Button>();
uiUse.gameObject.SetActive(true);
uiUse.transform.position = Camera.main.WorldToScreenPoint(this.transform.position + offset);
}
}
private void OnCollisionExit(Collision collisionInfo)
{
if(collisionInfo.collider.name == "Player")
{
Destroy(uiUse);
}
}
}
The code does exactly what you have written, which is destroying uiUse which is a Button component. If you go and inspect your game object in the scene, you will see, that indeed, the button component has been destroyed.
What you want to do is to destroy the GameObject the button component is attached to, like: Destroy(uiUse.gameObject)

I wanna disable a canvas and destroy the object when the player leaves the collider

I'm trying to make a animated UI and I wanna destroy the object after the player left the Collider and I don't really seem to find a way to do that.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.InputSystem;
public class Crate : MonoBehaviour
{
public float duration;
public GameObject animateObject;
public GameObject crateBox;
public Text crateText;
public GameObject crateImage;
public GameObject crate;
public bool playerInRange;
private bool crateOpened = false;
// Update is called once per frame
void Update()
{
if (crateOpened == false)
{
if (Keyboard.current.eKey.wasPressedThisFrame && playerInRange)
{
if (crateBox.activeInHierarchy)
{
crateBox.SetActive(false);
}
else
{
crateBox.SetActive(true);
crateOpened = true;
Animate();
}
}
if (crateOpened == true)
{
Destroy(animateObject);
}
}
}
private void OnTriggerEnter2D(Collider2D other) {
if(other.CompareTag("Player")) {
playerInRange = true;
crateImage.SetActive(true);
}
}
private void OnTriggerExit2D(Collider2D other) {
if(other.CompareTag("Player")) {
playerInRange = false;
crateBox.SetActive(false);
crateImage.SetActive(false);
}
}
private void Animate()
{
LeanTween.scale(animateObject, new Vector3(1f, 1f, 1f), duration);
}
}
I'm trying to make a animated UI and I wanna destroy the object after the player left the Collider and I don't really seem to find a way to do that.
I think the following is in the wrong place:
if (crateOpened == true)
{
Destroy(animateObject);
}
Try moving this inside the if statement in OnTriggerExit2D. What you are doing now is destroying your animateObject before it is animated. What I think you want is for animateObject to be destroyed when the player leaves the collider.

Particle system don't stop after one shot

I have a fps with a gun and when I shot the particle system continue to play . I want to do the effect of pistol shot:
I want the duration to be 0.5 sec or something
It just appears more and don't make the effect of one shot , they just fall down , what can I do?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SpawnProjectiles : MonoBehaviour
{
public GameObject firePoint;
public List<GameObject> vfx = new List<GameObject>();
private GameObject effectToSpawn;
public Button button;
// Start is called before the first frame update
void Start()
{
effectToSpawn = vfx[0];
button.onClick.AddListener(TaskOnClick);
}
// Update is called once per frame
void Update()
{
}
void SpawnVFX ()
{
GameObject vfx;
if(firePoint != null)
{
vfx = Instantiate(effectToSpawn, firePoint.transform.position, Quaternion.identity);
}else
{
Debug.Log("NoFirePoint");
}
}
void TaskOnClick()
{
SpawnVFX();
}
}
Uncheck Looping, otherwise the Particle system will keep emitting.

Script code only seems to work on single instance of prefb

I am experiencing the strangest issue
I have a ray cast and when it touches a certain layer it calls my function which does a small animation.
The problem is, this only works on a single object, I have tried duplicating, copying the prefab, dragging prefab to the scene, it doesn't work.
Now I have this code below, and as you can see I have this line which allows me to access the script on public PlatformFall platfall; so I can call platfall.startFall();
Something I've noticed, If I drag a single item from the hierarchy to the public PlatFall in Inspector then that SINGLE object works as it should. ( in that it animates when startFall is called). HOWEVER, if I drag the prefab from my project to the inspector then they do not work. (Even if debug log shows that the method is called animation does not occur).
public class CharacterController2D : MonoBehaviour {
//JummpRay Cast
public PlatformFall platfall;
// LayerMask to determine what is considered ground for the player
public LayerMask whatIsGround;
public LayerMask WhatIsFallingPlatform;
// Transform just below feet for checking if player is grounded
public Transform groundCheck;
/*....
...*/
Update(){
// Ray Casting to Fallingplatform
isFallingPlatform = Physics2D.Linecast(_transform.position, groundCheck.position, WhatIsFallingPlatform);
if (isFallingPlatform)
{
Debug.Log("Here");
platfall.startFall();
}
Debug.Log(isFallingPlatform);
}
}
Platform Script
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlatformFall : MonoBehaviour
{
public float fallDelay = 0.5f;
Animator anim;
Rigidbody2D rb2d;
void Awake()
{
Debug.Log("Awake Called");
anim = GetComponent<Animator>();
rb2d = GetComponent<Rigidbody2D>();
}
private void Start()
{
Debug.Log("Start Called");
}
//void OnCollisionEnter2D(Collision2D other)
//{
// Debug.Log(other.gameObject.tag);
// GameObject childObject = other.collider.gameObject;
// Debug.Log(childObject);
// if (other.gameObject.CompareTag("Feet"))
// {
// anim.SetTrigger("PlatformShake");
// Invoke("Fall", fallDelay);
// destroy the Log
// DestroyObject(this.gameObject, 4);
// }
//}
public void startFall()
{
anim.SetTrigger("PlatformShake");
Invoke("Fall", fallDelay);
Debug.Log("Fall Invoked");
// destroy the Log
// DestroyObject(this.gameObject, 4);
}
void Fall()
{
rb2d.isKinematic = false;
rb2d.mass = 15;
}
}
I understood from your post that you are always calling PlatformFall instance assigned from inspector. I think this changes will solve your problem.
public class CharacterController2D : MonoBehaviour {
private PlatformFall platfall;
private RaycastHit2D isFallingPlatform;
void FixedUpdate(){
isFallingPlatform = Physics2D.Linecast(_transform.position, groundCheck.position, WhatIsFallingPlatform);
if (isFallingPlatform)
{
Debug.Log("Here");
platfall = isFallingPlatform.transform.GetComponent<PlatformFall>();
platfall.startFall();
}
}
}
By the way, i assume that you put prefab to proper position to cast. And one more thing, you should make physics operations ,which affect your rigidbody, in FixedUpdate.

OnCollisionEnter in unity won't call function

I'm a complete unity novice. I want to make a simple scene where you have three lives and you lose a live if you collide with a cube. This is my script:
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
public class Lives : MonoBehaviour {
public Transform player;
public static int lives;
public Image live1;
public Image live2;
public Image live3;
// Use this for initialization
void Start () {
lives = 3;
live1.enabled = true;
live2.enabled = true;
live3.enabled = true;
}
void Update () {
DisplayOfHearts();
}
public static void Damage() {
lives -= 1;
}
public void OnCollisionEnter(Collision col) {
if (col.gameObject.tag == "cube") {
Lives.Damage();
}
}
public void DisplayOfHearts() {
if (lives == 2) {
live3.enabled = false;
}
else if (lives == 1) {
live2.enabled = false;
}
else if (lives == 0) {
live1.enabled = false;
}
}
}
What happens is the player can't move through the cube but the amount of lives stays three. Is there something I'm missing?
The problem is you have attached the script to a wrong game object. The script and the collider must be attached to the same game object.
Unity methods inside a MonoBehaviour script (such as OnEnable, Update, FixedUpdate, Awake, Start, OnTriggerEnter, OnCollisionStay, etc..) only work for the game object which the script is attached to.
If you attach the script to another game object don't expect any of those to work. Update only works while that game object is active. OnCollisionEnter only works when a collision occurs on a collider which is attached directly to that game object. (it doesn't even work when a child has the collider instead of the actual game object where script is attached to)