Problem with respawned camera in Unity3D in c# - c#

I have a problem with camera in Unity. I want to follow to the ball. I want to make auto respawn for the ball and camera. But the code works but camera doesn't follow to the ball.
This is code for auto respawn:
public class start : MonoBehaviour
{
public GameObject Camera;
public GameObject Ball;
void Start()
{
GameObject ball = GameObject.Instantiate(Ball);
Ball.name = "Ball";
ball.transform.position = transform.position + Vector3.up * 0.5f;
Instantiate(Camera);
Camera.name = "Camera";
Camera.transform.position = transform.position + new Vector3(0.25f, 1.75f, 6.5f);
}
The code for camera controller:
public Transform Ball;
void Update()
{
Rigidbody rigidbody = Ball.GetComponent<Rigidbody>();
float ballVelocity = rigidbody.velocity.sqrMagnitude;
UnityEngine.Vector3 vector = new UnityEngine.Vector3(0, 4, 7);
vector *= (1+ ballVelocity / 30);
UnityEngine.Vector3 nowaPozycjaKamery = Ball.position + vector;
transform.position = UnityEngine.Vector3.Lerp(transform.position, nowaPozycjaKamery, Time.deltaTime*5);
transform.LookAt(Ball);
}
Camera worked well before auto respawn. Code work that on start camera follow to good position, but is freezed when the ball change the position.

I wish you provided more information on this question. Like is there any NullReferenceException or other exceptions. But I'll try to answer your issue anyways. I think the problem is that the camera script doesn't have the reference to the new ball that's being spawned (this is in the case of destroying the old ball and Instantiating a new one with Destroy(gameObject)).
What I suggest is to add a Method in the camera script that will be in charge of injecting the new ball into the script. And then you call this method with the new spawned ball in the script responsible for spawning. Or a more straightforward but not efficient way is to check if the ball property is null and then you make a call to GameObject.Find("Name of The ball object") and you give the name of the ball object.

Related

Conflicting IF statements in Unity C# , Soccer Game

I am a starter in Unity and developing a soccer game. I have a problem ,my IF statements conflict each other. Let me explain it in detail.
In order for a ball to stick to player, I have used IF operator, so whenever the distance between the player and the ball is less than < 0.5 , the ball sticks to player and move together with it. Now when I try to set up shooting the ball (I try with "addforce") it doesnt let me, cause the ball is still attached to player and distance is <0.5.
This one is the balls script.
public bool sticktoplayer;
public transform player;
//gameobject Player is attached
float distancetoplayer;
Rigidbody rb;
//balls rigidbody
void Awake ()
{
rb = getComponent<Rigidbody>();
}
void Update()
{
If (!sticktoplayer)
{
float distancetoplayer = Vector3.Distance (player.position, transform.position);
if(distancetoplayer < 0.5f)
{
sticktoplayer = true;
}
}
else
{
transform.position = player.position;
}
if(Input.GetKeyDown(KeyCode.Space))
{
rb.addforce(20, 0, 0, ForceMode.Impulse);
sticktoplayer = false;
}
When the player is not controlling the ball the force is succesfully applied to the ball, but when the ball is attached (distancetoplayer<0.5) then the other IF statements blocks it from shooting.
Maybe there are some work arounds ? Thanks.
I tried to make another if statement.
why dont you try sticking the ball to the player by collision? instead of checking the distance, create a collider with the radius or scale you desire and whenever the ball is inside the collider (when it triggers with the collider) stick it to the player. Because you will not be able to let the ball go since the ball will always be less then 0.5f away from the player once it sticks
have you tried it this way?
if(Input.GetKeyDown(KeyCode.Space))
{
sticktoplayer = false;
rb.addforce(20, 0, 0, ForceMode.Impulse);
}

Unity3D Help - Shooting object in direction of player rotation

I'm making a third person sports game and I wish to shoot the ball straight forward from the player.
I have a working script for shooting the ball, however it is attached to the main camera so only shoots in the direction the camera is facing.
I would like to alter this code to attach it to the player instead of the camera.
PS: I am still very new to C#, I assume the problem is in the "camera.main.transform" section but I don't know the code to change it to player.
my code is below;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ShootScript : MonoBehaviour
{
public GameObject bulletPrefab;
public float shootSpeed = 300;
Transform cameraTransform;
void Start()
{
cameraTransform = camera.main.transform;
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
shootBullet();
}
}
void shootBullet()
{
//Get the Rigidbody that is attached to that instantiated bullet
Rigidbody projectile = GetComponent<Rigidbody>();
//Shoot the Bullet
projectile.velocity = cameraTransform.forward * shootSpeed;
}
}
First of all: You currently do GetComponent<Rigidbody> on that object itself .. this makes no sense since it would fire away "yourself" instead of a bullet. You have to Instantiate a bullet and apply forces/velocity here. You kind of missed the instantiation.
Then simply attach this script to your player Object instead and use transform.forward. transform returns the Transform component of the GameObject this script is attached to.
public class ShootScript : MonoBehaviour
{
// Hint: By making the prefab field Rigidbody you later can skip GetComponent
public Rigidbody bulletPrefab;
public float shootSpeed = 300;
void Update()
{
if (Input.GetKeyDown(KeyCode.Mouse0))
{
shootBullet();
}
}
void shootBullet()
{
// Instantiate a new bullet at the players position and rotation
// later you might want to add an offset here or
// use a dedicated spawn transform under the player
var projectile = Instantiate (bulletPrefab, transform.position, transform.rotation);
//Shoot the Bullet in the forward direction of the player
projectile.velocity = transform.forward * shootSpeed;
}
}

How can a make the camera follow a rolling ball from behind?

I am using unity 2018.3.5f1 so a few solutions to this problem don't work.
Starting from the Roll-A-Ball demo project, I want to extend the camera script to follow the player, but also keeping track of the direction of movement. Ex: If the ball starts moving to the side, I need the camera to rotate around the player's axis to position behind him, and then start following him.
I have tried making the camera a child to the ball i'm trying to control and i've tried making a script but it won't follow the ball correctly it keeps rotating the camera as well as the ball (i'm using this bit of code and trying to modify it as it's the only one that works)
here is the code I have at the moment:
using UnityEngine;
using System.Collections;
public class CompleteCameraController : MonoBehaviour
{
public GameObject player; //Public variable to store a reference to the player game object
private Vector3 offset; //Private variable to store the offset distance between the player and camera
// Use this for initialization
void Start()
{
//Calculate and store the offset value by getting the distance between the player's position and camera's position.
offset = transform.position - player.transform.position;
}
// LateUpdate is called after Update each frame
void LateUpdate()
{
// Set the position of the camera's transform to be the same as the player's, but offset by the calculated offset distance.
transform.position = player.transform.position + offset;
}
}
I understand why it is rotating but no reasearch is helping me find out how to lock the camera so it is looking behind the ball at all times
Have you tried adding some restraints to your camera? If it is only supposed to turn to follow the ball, you can freeze the position of 2 axes (x and z), and only let the camera rotate around the y axis of the ball.
You can play around with the restraints on the Inspector, or use GetComponent<Rigidbody>().constraints = RigidbodyConstraints.FreezeRotationX; in the camera script.
(EDIT) Sorry, this is how you would do it if the gameObject has a rigidbody, but the idea is the same if it doesn't have one.
When you're setting the position or rotation of the camera, think about which components of the position/rotation you actually want to change (x,y,z).
Use offset = new Vector3 (offset.x, offset.y, offset.z)and replace anything that shouldn't change with a constant.
Also, when you made the Camera the child of the ball, you could have set it so that every frame, the Camera updates in such a way that it won't roll with the ball. You could do this by putting code in the update method of the camera that sets the component x, y, or z equal to some constant. Whatever axis the ground plane is on is probably the correct choice.
If you want the same camera angle that the camera should follow while following the ball (similar to Temple Run), then try the below code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class CompleteCameraController : MonoBehaviour
{
public Transform Player;
public float distanceFromObject = 3f;
void Update()
{
Vector3 lookOnObject = Player.position - transform.position;
lookOnObject = Player.position - transform.position;
transform.forward = lookOnObject.normalized;
Vector3 playerLastPosition;
playerLastPosition = Player.position - lookOnObject.normalized * distanceFromObject;
playerLastPosition.y = Player.position.y + distanceFromObject / 2;
transform.position = playerLastPosition;
}
When the ball moves left or right, the camera will follow the same angle as the ball moves towards.

Prevent object from passing through collider

I am building a 3D maze that is moved by the player. I'm taking a "labyrinth" approach and having a small ball be maneuvered through the maze when the player moves the maze. The problem occurs when the player moves a wall that the ball is currently resting on in the direction of the ball. The ball passes through the wall and stops on the next available wall.
The maze uses a mesh collider and rigidbody and the ball is a sphere collider.
I have drastically increased the physics frame rate to no avail. Considering the complexity of the maze and the potentially large number of maze combinations I really don't want to attach simple colliders to every wall. Any tips, tricks, suggestions, comments, etc. would be appreciated.
Ball Script for continious rotation:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ballGravity : MonoBehaviour {
public Rigidbody m_Rigidbody;
public Vector3 m_EulerAngleVelocity;
// Use this for initialization
void Start () {
m_EulerAngleVelocity = new Vector3 (0, 100, 0);
m_Rigidbody = GetComponent<Rigidbody>();
}
// Update is called once per frame
void FixedUpdate () {
Quaternion deltaRotation = Quaternion.Euler (m_EulerAngleVelocity * Time.deltaTime);
m_Rigidbody.MoveRotation (m_Rigidbody.rotation * deltaRotation);
}
}
Maze Rotation Script:
using UnityEngine;
using System.Collections;
public class rotObj : MonoBehaviour
{
private float baseAngle = 0.0f;
float rotSpeed = 10;
void OnMouseDown(){
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
baseAngle = Mathf.Atan2(pos.y, pos.x) * Mathf.Rad2Deg;
baseAngle -= Mathf.Atan2(transform.right.y, transform.right.x) *Mathf.Rad2Deg;
}
void OnMouseDrag(){
//float rotY = Input.GetAxis("Vertical")*rotSpeed*Mathf.Deg2Rad;
//gm.transform.Rotate(Vector3.right, rotY);
Vector3 pos = Camera.main.WorldToScreenPoint(transform.position);
pos = Input.mousePosition - pos;
float ang = Mathf.Atan2(pos.y, pos.x) *Mathf.Rad2Deg - baseAngle;
transform.rotation = Quaternion.AngleAxis(ang, Vector3.forward);
}
}
To get consistent physics state its best to move colliders within FixedUpdate - if you move colliders in a OnMouseXX stage of the pipeline (Consider consulting https://docs.unity3d.com/Manual/ExecutionOrder.html), you risk that the change might be missed next time FixedUpdate is called. I.e. your ball moves through the state of your scene based on how it was before you rotated the maze, and with some unfortunate timings its possible that collisions get missed.
If you already tried with a tighter timestep, consider queueuing the OnMouseDrag change, like store the resulting rotation in a variable, and apply it in FixedUpdate, so it is applied just in case for next physics computation.
you may also consider moving your ball at the same time as you rotate your maze, quickly moving a mesh collider against a much smaller rigidbody is a sure source of trouble. Can you move a camera instead ?

Unity3d C# turret gun projectile won't move

I'm working on a gun turret. I've got everything working except having the projectile shoot out of the turret gun barrel. Currently, the only barrel used is
void Start(){
firingPointRight = GameObject.FindGameObjectWithTag ("FiringPointRight").transform;
firingPointLeft = GameObject.FindGameObjectWithTag ("FiringPointLeft").transform;
}
void Update() {
if(Input.GetMouseButton(0)){
count++;
if (count >= maxCount)
{
count = 0;
//Debug.Log ("FIRE");
firingPointRight = GameObject.FindGameObjectWithTag ("FiringPointRight").transform;
firingPointLeft = GameObject.FindGameObjectWithTag ("FiringPointLeft").transform;
// Create cannon muzzle fire effect.
GameObject e1 = Instantiate (cannonMuzzleFire) as GameObject;
e1.transform.position = firingPointRight.transform.position;
e1.transform.rotation = firingPointRight.transform.rotation;
Destroy (e1, 0.03f);
GameObject e2 = Instantiate (cannonMuzzleFire) as GameObject;
e2.transform.position = firingPointLeft.transform.position;
e2.transform.rotation = firingPointLeft.transform.rotation;
Destroy (e2, 0.03f);
//-------------------------------------------
//Left cannon. Fire projectile from cannon.
//Debug.Log ("Firing Left");
Rigidbody InstantiateedProjectile = Instantiate(cannonAmmo, firingPointLeft.transform.position, firingPointLeft.transform.rotation) as Rigidbody;
if (InstantiateedProjectile != null)
{
print ("Firing projectile");
InstantiateedProjectile.transform.Translate(Vector3.forward * cannonAmmoSpeed * Time.deltaTime);
}
}
}
Does the projectile have a script of its own? It doesn't look like you're setting any velocity to the instantiated projectile.
Translate() doesn't really perform much in the way of movement, other than immediately setting the new position. If the projectile has a Rigidbody component attached, then you can just directly set the velocity of the rigidbody.
Like so:
InstantiateedProjectile.velocity = Vector3.forward * cannonAmmoSpeed;
Time.deltaTime wouldn't be used here, since it only needs to be included in calculations performed every frame.
As a side note, you might wish to consider reusing your flare effect instead of spawning a new one every shot. You can make the effect invisible and reset it between shots instead, which would give better performance.

Categories

Resources