I can't get my GameObject to smoothly rotate between two angles - unity3d

So I'm using this code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class wands : MonoBehaviour
{
public Transform WandPos;
void Update()
{
WandPos.rotation = Quaternion.Lerp(new Quaternion(0,0,1,0), new Quaternion(0,0,0.866025448f,0.49999994f),Time.time * .5f);
}
}
For some reason it is preforming the rotation before the GameObject even rotates, so when it instantiates, the GameObject snaps to where it would be if it instantiated when the scene started. I'm probably just missing something obvious, but I can't seem to find my solution anywhere online either.
Also, if there is an easier way to do this than with the code I've written, please tell me.

Well Time.time is the time in seconds since you started the application!
Sounds like you rather wanted to track the time since you instantiated the object so e.g. like
private float time;
void Update ()
{
time += Time.deltaTime * 0.5f;
WandPos.rotation = Quaternion.Lerp(new Quaternion(0,0,1,0), new Quaternion(0,0,0.866025448f,0.49999994f), time);
}

Related

Better movement script needed?

I got an issue that I've been trying to figure out for some time now and still haven't managed. I created a script for movement which besides using the WASD keys also uses two more buttons to go up and down. The thing is - because of the way I added those buttons for some reason no other function regarding position of the player doesn't work well. For example if I put a collider with a simple on trigger transform.position function for the player to hit - the player is placed on that position but then instantly returned back like there was nothing.
Here is my code. I had tons of iterations how this movement can be done. I did it through physics and controller in several ways but nothing helped. Can you guys tell me if it's the code or some hidden Unity synergy that I don't know about?
(this version works around addForce. Regardless, whatever way I make the up and down functions I cannot move the player with script after that.)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Mov : MonoBehaviour
{
private CharacterController controller;
private Rigidbody Rb;
private Vector3 playerVelocity;
private float playerSpeed =12;
void Start()
{
controller = gameObject.AddComponent<CharacterController>();
Rb = gameObject.GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate()
{
Vector3 move = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
Vector3 add =new Vector3 (0, playerSpeed, 0);
controller.Move(move * Time.deltaTime * playerSpeed);
if (Input.GetKey(KeyCode.Mouse1))
{
Rb.AddForce(0, 1200, 0, ForceMode.Acceleration);
}
if (Input.GetKey(KeyCode.Mouse0))
{
Rb.AddForce(0, -1200, 0, ForceMode.Acceleration);
}
}
}
I'm not sure what you mean by "no other function regarding position of the player doesn't work well" but from have you turning "Collision Detection" in your Rigidbody's settings to "Continuous" and "Interpolate" to "Interpolate"? If you don't do so, Unity's collision's may be a bit funky especially if you are going at high speeds.

how can i fix "GameObject has been destroyed but you are still trying to access it" - unity

I am in process to make a 3D fps game with unity. But when i wrote the code to destroy the bullet after a particular time say - 5 seconds, till 5 seconds it spawnes the bullet and after 5 seconds the bullets spawned bullets get destroyed. But after that when i try to again spawn bullets, they dont get spawned and it shows the error GameObject has been destroyed but you are still trying to access it.
here is the destroy bullets code
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine;
public class Bullet : MonoBehaviour
{
public float speed = 8f;
public Camera playerCamera;
public float lifeDuration = 2f;
private float lifeTimer;
void Start()
{
lifeTimer = lifeDuration;
}
// Update is called once per frame
void Update()
{
transform.position += playerCamera.transform.forward * speed * Time.deltaTime;
lifeTimer -= Time.deltaTime;
if (lifeTimer <= 0f)
{
Destroy (gameObject);
}
}
}
I believe that when you destroy the GO, the reference to that object may be lost too. In your case, in which you're using bullets, I recommend you to instead of using Destroy(gameObject), use gameObject.SetActive(false) and recycle the bullets with a pool of bullets that you instantiate at the start of the game. That way is easier to have a reference to the GO and optimize the cost of instantiating x bullets.
This error occurs when you try to access a gameobject which has been destroyed.
how do you spawn the bullet?
if it's a prefab,i suggest you do like this,and DO NOT call this gameobject in any other script after its "lifeTime":
var go = GameObject.Instantiate( Resources.Load( "bullet prefab path" ) ) as GameObject;
go.AddComponent<Bullet>();
if not, i think you're Instantiate a gameobject already exist in Hierarchy.
//if the "prefab" is already exist in Hierarchy with script "Bullet" and is active
//this "prefab" will be destroyed by your bullet script after "lifeTime"
//when the next time you Instantiate() with this "prefab"
//you'll get the error:"GameObject has been destroyed but you are still trying to access it"
GameObject go = GameObject.Instantiate(prefab) as GameObject;

Pooled GameObject in Unity destroys itself after SetActive if Force is applied

When I retrieve an object from a list of created objects and reactivate it, it destroys itself, but only if I have force applied to start it moving. If I never apply force, everything works as intended and I can keep activating the object over and over.
I've tried putting a debug.log in the OnCollision and it isn't colliding with anything.
As said above, if I never initiate speed, the rest works fine.
When speed is applied, the first projectile works, the second destroys itself.
I've tried manually activating them instead of by code. Same result.
Exception: If I manually activate/deactivate objects myself through the inspector, they work if I only have 1 shot in the pool.
The one shot rule doesn't work if I do it through code. It breaks even if I only have one shot.
All the code worked when I wasn't using pooling.
Spawn code:
void CreateBullet(int GunID)
{
GameObject ShotFired = Guns[GunID].GetComponent<Weapon>().FireWeapon();
if (ShotFired == null)
{
ShotFired = Instantiate(Guns[GunID].GetComponent<Weapon>().Projectile,Guns[GunID].gameObject.transform);
Physics.IgnoreCollision(ShotFired.GetComponent<SphereCollider>(), Guns[GunID].GetComponentInParent<CapsuleCollider>());
Guns[GunID].GetComponent<Weapon>().AmmoPool.Add(ShotFired);
}
ShotFired.transform.position = Guns[GunID].transform.position;
ShotFired.transform.rotation = Guns[GunID].transform.rotation;
ShotFired.SetActive(true);
}
Projectile Code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Mirror;
public class Projectile : NetworkBehaviour
{
public float Speed;
public float LifeTime;
public float DamagePower;
public GameObject ExplosionFX;
// Start is called before the first frame update
void Start()
{
GetComponent<Rigidbody>().AddRelativeForce(Vector3.up * Speed, ForceMode.VelocityChange);
StartCoroutine(DeactivateSelf(5.0f));
}
private void OnDestroy()
{
Debug.Log("WHY!");
}
IEnumerator DeactivateSelf(float Sec)
{
yield return new WaitForSeconds(Sec);
Explode();
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.GetComponentInChildren<Vehicle>())
{
collision.gameObject.GetComponentInChildren<Vehicle>().CmdTakeDamage(DamagePower);
}
Explode();
}
void Explode()
{
GameObject ExplosionEvent = Instantiate(ExplosionFX, this.transform.position, Quaternion.identity);
NetworkServer.Spawn(ExplosionEvent);
GetComponent<Rigidbody>().AddRelativeForce(Vector3.zero);
gameObject.SetActive(false);
}
}
Any thoughts welcome. Thanks in advance!
In case anyone else stumbles across this, here's what happened and why assigning a movement speed to the object was what caused the issue.
My projectiles had a 'trailrenderer' on them.
By default 'Autodestruct' is true.
Autodestruct does not destruct the trail, but the game object when the trail disappears. So if you disable anything that had a trail, and activated it through movement, when the object stops moving (say to reposition in an object pool) it will destroy the parent object.
If the object never moves, it never generates a trail, and never needs to be destroyed.
To fix, just uncheck autodestruct.
https://docs.unity3d.com/ScriptReference/TrailRenderer-autodestruct.html

2D Camera movement script throwing CS0428

I'm trying to get a camera to move whenever you press either WASD or the arrow keys, but it's throwing
Error CS0428 Cannot convert method group 'GetComponent' to non-delegate type 'Transform'. Did you intend to invoke the method?
On this script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class cameramover : MonoBehaviour
{
public Camera controlled;
Vector3 movement;
void Start()
{
Transform transform1 = controlled.GetComponent<Transform>;
}
void Update()
{
movement = new Vector3(Input.GetAxis("Horizontal"), Input.GetAxis("Vertical"), 0.0f);
}
}
I tried invoking the method, but that threw CS0201, so I tried doing
new Transform(controlled.GetComponent<Transform>;)
and that didn't work either, so I went here to ask for help.
Figured it out with the help of the wonderful people at the Game Dev Network discord server! i just had to add a pair of parentheses on the end of the controlled.GetComponen;

Unity Random is detroying all objects

I'm trying to make the system work so that when a game starts and for each wall, it will either be in the game or not, randomly. Somehow, when I run it, it either keeps or destroys all the walls. How do I fix this?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class WallGen : MonoBehaviour{
public GameObject wallObject;
System.Random rnd = new System.Random();
// Use this for initialization
void Start () {
generate();
}
void generate()
{
int number = rnd.Next(1, 5);
if (number == 2)
{
OnDestroy();
}
}
private void OnDestroy(){
Destroy(wallObject);
}
// Update is called once per frame
void Update () {
}
}
Every time you do new System.Random() it is initialised using the clock. Now as the Start function is called at the same time, you get the same value for all the gameobjects. You should keep a single Random instance for all gameobjects and keep using Next on the same instance.
Or the easy solution
just Use Random.Range (1,5) instead of rnd.Next(1, 5);
As a side note, don't use the function name OnDestroy, as it is one of the MonoBehaviour functions in Unity and is called automatically when the attached gameobject is destroyed.