Shooting a ball from the middle of the camera - unity3d

I;m trying to make the first person character to shoot a ball from the middle of the camera,
but it's just not working.
Here is the first person character's script:
public Rigidbody ball;
void Update () {
if (Input.GetButtonDown ("Fire1")) {
Instantiate(ball,transform.position+new Vector3(0,1,0),transform.rotation);
}
}
and here is the ball's script :
public float speed=20;
Vector3 direction;
void Start () {
direction = Camera.main.transform.forward;
}
void Update () {
transform.Translate(direction *Time.deltaTime*speed);
Destroy(gameObject,3);
}
The ball is prefab.The problem is that the ball is not coming from the center of the camera.
I dont understand why its not working.
Anyone can help me?
Thank you!

The reason why your script does not work is the wrong position in Instantiate function, because you shouldn't assume that that player is facing into positive Y axis direction.
Code of instantiation should look like this:
Instantiate(ball,transform.position + transform.forward*(distance_from_camera),transform.rotation);
We set position to players transform.position increased by "forward" vector (it indicates in which direction object is facing), multiplying this value by distance in which instantiated object will appear.
Edit: 1. In ball script the direction should be just transform.forward.
2. Instantiated ball should have forward direction equal to camera's forward. To achieve this you have to set the ball to be child of camera, the change localRotation to (0, 0, 0). After it "unchild" the ball, so it won't have a parent.

You were so close! you just needed to instantiate it at the cameras position!
void Update () {
if (Input.GetButtonDown ("Fire1")) {
Instantiate(ball,Camera.main.transform.position,transform.rotation);
}
}

Related

How to lock the Y-axis for unity's Cinemachine?

I have a ball which we can throw here and there in my game. I want my cinemachine vcam to move only in the x direction with the ball. And just look up to the ball while its in air. I don't want the camera to move in y direction along it too.
I have set the look at and follow fields to the ball only. All i want it the camera to not follow the ball in y. (Basically, follow the ball in x, and keep looking at it in the air)
How can I achieve this is the most trivial and beautiful way possible? (open to scripts, but the lesser code the better)
as i've just tested, You can write a script that attaches to your camera, where you create a new vector3 with the x of your ball, and the frozen Y values that you want here's an exemple:
public class CameraController : MonoBehaviour
{
//Assign your ball in the inspector
public Transform target;
// Update is called once per frame
void Update()
{
//Here i assumed that you want to change the X
Vector3 newCamPosition = new Vector3(target.position.x, yourValue, yourValue);
gameObject.transform.position = newCamPosition;
}
}
Hope It helped <3

On Finger Touch and Drag Rotate 3D Ball - Unity 3D

My 3d ball was moving continuously in the forward direction so I want to give X-rotation for this plus game player was dragging ball horizontally on the screen so for this horizontal movement, I want to give Z-rotation.
To achieve my desire, the result I have made ball parent and child game objects, where parent game object only contains collider and rigidbody and this will do the actual physical movement.
Another side, child game object only contains mesh renderer, this will do desire rotation.
Following image gives you more idea about my structure:
Ball Parent:
Ball Child:
For giving rotation to ball mesh as like parent physics ball, I have written this code:
public class BallMeshRolling : MonoBehaviour
{
private Vector3 ballLastPosition;
void Start ()
{
ballLastPosition = transform.parent.position;
}
void Update ()
{
//implementation-1
//float speed = Vector3.Distance (transform.parent.position, ballLastPosition) * 30f;
//transform.RotateAround (transform.position, Vector3.right, speed);
//implementation-2
//Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized;
//transform.Rotate (differenceInPosition * 10f);
//implementation-3
Vector3 differenceInPosition = (transform.parent.position - ballLastPosition).normalized * 50f;
Quaternion rotation = Quaternion.LookRotation(differenceInPosition);
transform.rotation = rotation;
ballLastPosition = transform.parent.position;
}
}
But none of the above ways working properly, so I expect some other better suggestions from your side.
EDIT: Overall I am trying to achieve something like this:
Catch up - Ketchapp - Highscore 1274
There is a tutorial series from Unity about rolling and moving a 3d ball that can help you to figure out the basics for your problem. Wish it could help.
Roll-a-ball tutorial in Unity Tutorials

Unity3D follow Sphere player camera rotation

Hi I'm trying to get my camera to follow my player (Sphere) when ever it moves around. I have got the camera to follow the player, but when the sphere spins, so do the camera. That is not what i'm looking for. I need the camera to stay put on the sphere and rotate when I turn. This is my code so far:
EDIT: What I'm looking for is something like you see in the vid. where the camera rotate when the sphere is turning, so it's behind it all the time. https://www.youtube.com/watch?v=jPAgPQi1l0c
using UnityEngine;
using System.Collections;
public class TransformFollower : MonoBehaviour
{
[SerializeField]
private Transform target;
[SerializeField]
private Vector3 offsetPosition;
[SerializeField]
private Space offsetPositionSpace = Space.Self;
[SerializeField]
private bool lookAt = true;
private void Start()
{
offsetPosition = new Vector3(-3, -2, 0);
}
private void Update()
{
Refresh();
}
public void Refresh()
{
if (target == null)
{
Debug.LogWarning("Missing target ref !", this);
return;
}
// compute position
if (offsetPositionSpace == Space.Self)
{
transform.position = target.TransformPoint(offsetPosition);
}
else
{
transform.position = target.position + offsetPosition;
}
// compute rotation
if (lookAt)
{
transform.LookAt(target);
}
else
{
transform.rotation = target.rotation;
}
}
}
You should implement the following logic:
Create an empty gameObject:Character, where it will have as childs: Camera, Sphere
when you move, you simply transform the Character, so the Camera and the Sphere transform in the exact same way.
Now, when you want to rotate only the Sphere, but not the camera, just apply your rotation(or anything else), only in the sphere.
To do so, in your script you can pass the Character and the Sphere.
So moving transformations will be applied in on the Character and any custom move, only in the sphere.
Nik
Did you write this code yourself?
It simply seems that if lookat is true, it will do what you want. If it is false, if will do what you describe.
Just look in the editor and check the 'look at' box.
If you never want to use it you can remove it from the code by removing the lookat variable and replacing
// compute rotation
if (lookAt)
{
transform.LookAt(target);
}
else
{
transform.rotation = target.rotation;
}
by
// compute rotation
transform.LookAt(target);
EDIT more explanation:
In your code, you have two options: lookat and offsetPositionSpace.
Basically, offsetPositionSpace can be two values:
Self -> The camera will always be behind the player (if you rotate the player, it moves to stay behind
World -> The camera will always imitate the player's moves (If the player rotates, the camera won't move
LookAt can also have two values
true -> the camera looks at the player, always
false -> the camera imitate the players rotation (if the player rotates, the camera does the same and stops looking at the player)

Camera Move and Rotate Follow Player very jerky

I make a character move on the surface of a circle. I let the camera move and rotate follow character. But the camera move and rotate very jerky. If I increase the value of the third parameter, the shock increases. and to reduce the value of the third parameter, the camera does not rotate to keep up the character. Help me fix it
My Code Camera Follow Player
public class CameraFollow : MonoBehaviour
{
public Transform player;
GameController gc;
public float speed = 2;
Vector3 pos = new Vector3 (0, 0, -10);
// Use this for initialization
void Start ()
{
gc = FindObjectOfType (typeof(GameController)) as GameController;
}
void FixedUpdate ()
{
if (gc.gameState == GameController.GameState.playing || gc.gameState == GameController.GameState.changeWave) {
transform.position = player.position + pos;
transform.rotation = Quaternion.Slerp (transform.rotation,
player.transform.rotation,
speed * Time.deltaTime);
}
}
}
Setting the position of a transform inside of FixedUpdate is a red flag for sure, especially when you're reporting that it's "jerky". Fixed update happens at an irregular interval compared to the frames displayed. This is because Physics needs to update using a fixed time step. The reason why this is the case is out of scope for this question.
Long story short, try changing FixedUpdate to Update and that should fix things looking "jerky".
Let me know if this doesn't work and I'll look for other possible causes.
If you are using a Rigidbody2D to move the character, make sure to set its Interpolate property to 'Interpolate'. This should fix it.

Unity - How to instantiate new object with initial properties (like velocity)?

I'm trying to implement a tower defense game in Unity, and I can't figure out how can I assign a velocity or a force to a new instantiated object (in the creator object's script)
I have a tower which is supposed to shoot a bullet towards the enemy which triggered its collider. This is the script of the towers:
function OnTriggerEnter(other:Collider){
if(other.name=="Enemy")
{
ShootBulletTo(other.transform);
}
}
function ShootBulletTo(target:Transform)
{//public var Bullet:Transform
var BulletClone = Instantiate(Bullet,transform.position, Quaternion.identity); // ok
BulletClone.AddForce(target.position); //does not compile since Transform.AddForce() does not exist.
}
I guess the problem is I have to use a Transform variable for instantiate but I need a GameObject variable for velocity, force etc. So how can I instantiate the bullet with initial velocity?
Thanks for help.
You have to acces the rigidbody component of your bullet clone to change the force, not the transform.
Here's how your code should look:
function OnTriggerEnter(other:Collider)
{
if(other.name=="Enemy")
{
ShootBulletTo(other.transform);
}
}
function ShootBulletTo(target:Transform)
{
var Bullet : Rigidbody;
BulletClone = Instantiate(Bullet, transform.position, Quaternion.identity);
BulletClone.AddForce(target.position);
}
There's also a good example in the unity script reference
http://docs.unity3d.com/Documentation/ScriptReference/Object.Instantiate.html
[EDIT] I'm pretty sure, that you don't want to add the enemies position as a force, instead you should add a direction that goes towards the enemies position.
You subtract two positions to gain a direction vector between them, so the ShootBulletTo function should look like this:
function ShootBulletTo(target:Transform)
{
// Calculate shoot direction
var direction : Vector3;
direction = (target.position - transform.position).normalized;
// Instantiate the bullet
var Bullet : Rigidbody;
BulletClone = Instantiate(Bullet, transform.position, Quaternion.identity);
// Add force to our bullet
BulletClone.AddForce(direction);
}