shoot ball from middle of the screen Unity - unity3d

Hi im trying to create a sphere and launch it in the direction im looking from the middle of the screen.
however im currently launching from the middle but always in the same direction and height.
tanx for any help.
#pragma strict
private var globe:GameObject;
var globeMaterial:Material;
private var shootIndex:boolean;
function Start () {
}
function Update () {
if(Input.GetMouseButtonDown(0))
{
if (shootIndex==false){
globe=GameObject.CreatePrimitive(PrimitiveType.Sphere);
globe.renderer.material=globeMaterial;
globe.AddComponent(Light);
globe.light.color=Color.blue;
globe.AddComponent(Rigidbody);
//globe.transform.position=Camera.main.ScreenToViewportPoint(Input.mousePosition);
globe.transform.position=Camera.main.transform.position;
globe.transform.localScale=Vector3(0.5,0.5,0.5);
globe.rigidbody.AddRelativeForce(Vector3.forward*1000);
shootIndex=true;
}
else if (shootIndex==true){
Destroy(globe);
shootIndex=false;
}
}
}

Your Problem is that Vector3.forward is always the Vector (0,0,1) as in one step towards the z coordinate(in this analogy y is upwards and x is right) as can be seen here:
http://docs.unity3d.com/Documentation/ScriptReference/Vector3-forward.html
Two solutions to this are:
1.) Add the Force in the direction your camera is pointing:
globe.rigidbody.AddForce(Camera.main.transform.forward * 1000);
You dont need "AddRelativeForce" here as your Globe isnt rotated in any way. so "AddForce" and "AddRelativeForce" have the same effect.
2.) Or change the rotation of the sphere and then send the sphere forwards (relative to its own rotation):
globe.transform.rotation = Camera.main.transform.rotation;
globe.rigidbody.AddRelativeForce(Vector3.forward * 1000);

Related

how to make rigidbody slide on diagonal wall collision

I'm struggling a lot with moving Rigidbodies, currently I have this method to move player:
private void SimpleMove()
{
var scaledMovementSpeed = movementSpeed;
_isRunning = false;
if (Run)
{
scaledMovementSpeed *= runMultiplier;
_isRunning = true;
}
var trans = transform;
var forward = trans.forward;
var newDirection = Vector3.RotateTowards(forward, SimpleMoveVector, Time.fixedDeltaTime * rotationSpeed, 0.0f);
trans.rotation = Quaternion.LookRotation(newDirection, trans.up);
var velocity = _rigidbody.velocity;
var velocityChange = new Vector3(forward.x * scaledMovementSpeed, velocity.y, forward.z * scaledMovementSpeed) - velocity;
_rigidbody.AddForce(velocityChange, ForceMode.VelocityChange);
_isMoving = true;
}
Map is build out of simple cubes right now and the player has capsule collider on him with freeze rotation on all axes.
By tweaking force values a little bit I managed to get it to work properly without the need to check for collisions myself but
expected behavior of player going diagonally into wall is to slide perpendicular to its surface. When I get close to cube's corner character slides across but when I'm going diagonally into a wall character just stops. Haven't tried it with analog input yet.
Is there a way to properly make character slide (fe. put proper physics material on him, or the wall?) or do I need to explicitly check and manage these collisions myself for that?
I thought that my turn-and-then-go-forward method might be messing with proper colliding, but I made the turn instant and the behavior was exactly the same.

Unity Navmeshagent won't face the target object when reaches stopping distance

I'm trying to get the NPC to look at the main character when I'm talking to him. I need to make sure it looks natural and that he is facing me. I know I can do Transform.LookAt() but that is too instant and unnatural.
How do I rotate the navmeshagent to face my character when its stopped moving?
Try this out to control the body orientation - the slerp is adjustable to your desired rotation speed (https://docs.unity3d.com/ScriptReference/Quaternion.Slerp.html):
private void FaceTarget(Vector3 destination)
{
Vector3 lookPos = destination - transform.position;
lookPos.y = 0;
Quaternion rotation = Quaternion.LookRotation(lookPos);
transform.rotation = Quaternion.Slerp(transform.rotation, rotation, [fill in desired rotation speed]);
}
if(agent.remainingDistance < agent.stoppingDistance)
{
agent.updateRotation = false;
//insert your rotation code here
}
else {
agent.updateRotation = true;
}
This will rotate your agent when it's distance below the stoppingDistance variable. However it will look inhuman, so if you're going for a humanoid ai I'd recommend looking at the unity Mecanim demo (particularly the locomotion scene) as it has code and animations that will properly animate the agent.
Maybe try this Head Look Controller. It's very smooth and blends with animations!
Put the char in a game object and copy the navmesh from the char to the parent, uncheck enable in char. move any scripts up too.
Just spent 5 hours to find this.

Move a particular sprite to a target position on touch in unity 4.6

I have just started unity. I have 4 Images(sprites) aligned in a grid. Now i want to move an image to a target position as soon as I touch the image. How can i do that?
I wrote the following code for move:
void Update () {
float step=speed*Time.deltaTime;
transform.position=Vector3.MoveTowards(transform.position,target.position,step);
}
I just don't know to move that particular sprite on which I touch.
Thanks
From http://answers.unity3d.com/questions/420808/how-to-get-position-of-touch-on-touch-screen.html
fingerPos = Input.GetTouch(0).position;
Vector3 pos = fingerPos;
pos.z = transform.position.z;
// simplified check
if (transform.position == Camera.main.ScreenToWorldPoint(pos))
{
// move towards the target as you want
}
Notice that i kept it brief with that if, but, of course, you should check if the touch position is withing the boundaries of your object.

How can i turn the camera to left and right in unity for a sphere?

updated CODE .. the problem is that i cant move the ball only if i hold the E button than i use WASD or arrows to move the ball...and when i hold Q the camera 2 activates and i can move the ball with WASD or arrows...but with the right axis for that angle...is like ballance that game... i want to not hold the E or Q just to change the camera and move the ball corecctly for that angle with the right axis for the ball but not holding the cameras button
using UnityEngine;
using System.Collections;
public class controlPlayer : MonoBehaviour {
public float viteza ; // this is speed
;
void Start(){
}
void Update()
{
if(Input.GetKey(KeyCode.Q) ) // if i hold Q the camera 2 activates and with WASD i can move the ball
{
float miscaOrizontal = Input.GetAxis("Horizontal");
float miscaVertical = Input.GetAxis("Vertical");
Vector3 miscare = new Vector3(miscaVertical,0.0f,(-miscaOrizontal)); //also here i chande the axis for the camera 2
rigidbody.AddForce(miscare * viteza * Time.deltaTime);
}
if(Input.GetKey(KeyCode.E) ) // here when i press E the camera 1 activates and alos i can move the ball if i keep pressing E
{ float miscaOrizontal2 = Input.GetAxis("Horizontal");
float miscaVertical2 = Input.GetAxis("Vertical");
Vector3 miscare2 = new Vector3(miscaOrizontal2,0.0f,miscaVertical2); // here are the controls for the ball for the camera ..i had to change the axis here..
rigidbody.AddForce(miscare2 * viteza * Time.deltaTime);
}
}
}
}
Alright, so if I'm understanding you correctly, you want the ball to move in relation to which direction the camera is currently facing. As well as you don't want to have to hold down "Q" or "E" while you move your ball with WASD controls.
So there are a few things that I'd like to mention here, so we'll take them one at a time. First off, you shouldn't have "AddForce" inside of an Update call. Update is called every frame whenever it can. It's great for input, but generally you want to call it in "FixedUpdate" instead. It provides a better response across many devices. If you leave it in update, you can get inaccurate physics results, and missed collisions. There's a lot out there on this subject, so if you want to know more about it, then just google for a little while.
As for the code side, you want to store a reference to what camera you're using to avoid having to hold these buttons down.
What I mean is:
private Camera referencedCamera = null;
private void Start()
{
referencedCamera = camera1;
}
private void Update()
{
if(Input.GetKey(KeyCode.Q)) referencedCamera = camera2;
else if(Input.GetKey(KeyCode.E)) refrencedCamera = camera1;
}
This way you can reference which camera is being used, rather than a key input. Something else to look into is the "State Design Pattern". Below is a video over the "State Design Pattern." That is a great video tutorial series that Derek Banas put up on design patterns, extremely recommend watching them, but the state pattern could potentially solve this problem for you as well. So that should take care of not having to hold the button down in order to make the move. More or less, the buttons will now allow you to just switch which camera is currently being used.
https://www.youtube.com/watch?v=MGEx35FjBuo
So now that that is solved, you want to transform the input that you currently have, and you want to put it in terms of hte camera that is currently being used. So to avoid rewriting a lot of the code over and over again, just know that these two code snippets should be pieced together into one. So "referencedCamera" should be already defined in the code I'm about to write:
private void FixedUpdate()
{
if(referencedCamera != null)
{
float miscaOrizontal = Input.GetAxis("Horizontal");
float miscaVertical = Input.GetAxis("Vertical");
Vector3 miscare = referencedCamera.transform.TransformDirection(
new Vector3(miscaVertical, 0.0f, -miscaOrizontal));
rigidbody.AddForce(miscare * viteza * Time.deltaTime);
}
}
So now with this, is it's the same code, but there is a call to the referenced cameras transform to take the vector 3 from the input and put it in relation to the camera instead, and add the new relational vector to the object.
I also want to recommend you looking into events rather than if checks in the update function, but that is beyond the scope of the question. Hope this helps and any questions, don't hesitate to ask.
EDIT
After further discussion, we came across something that should also be mentioned. If your camera that you are referencing is angled, the force will be applied in that angle, so keep that in mind. If it is pointed towards an object downward, then forward relative to the camera will apply a force downward, and not entirely in what you may consider the forward direction. Thought it was worth mentioning.

Unity - Walk around a cube

I have an issue with trying to get an 'object(character)' to walk around a cube (all sides) within Unity. Ive attached an image and video showing what i am trying to achieve. Im trying to show you visually rather than trying to explain. As the character drops over the edge it rotates 90 degrees and then the stands up like gravity has switched. Then the character can jump walk etc.
This is an example of someone else that posted a video showing exactly what im trying to achieve
I have looked through the forums and cant find what im after. i have tried to attach a diagram but the site wont let me. Any advice would be greatly appreciated!
Regards
Nick
You have a couple of options that I can think of.
One is to trigger the gravity change when the character exits one face of the cube to go to another. To achieve this you would have trigger zones on each edge and face and use a [Bob went from Face A to Edge ANorth -> Switch Gravity to go in X direction].
This would work for situations where the gravity switch must affect other objects too but be advantageous to your player (walking off the side makes an enemy fall off and die - for example.)
However, if you want all entities to stick to their relative sides then we need to make custom gravity! To do this is easier than you might think as gravity is simply a downward accelleration of 9.8. So turn off the engines native gravity and create a "personal gravity" component:
private Vector3 surfaceNormal;
private Vector3 personalNormal;
private float personalGravity = 9.8f;
private float normalSwitchRange = 5.0f;
public void Start()
{
personalNormal = transform.up; // Start with "normal" normal
rigidbody.freezeRotation = true; // turn off physics rotation
}
public void FixedUpdate()
{
// Apply force taking into account character normal as personal gravity:
rigidbody.AddForce(-personalGravity * rigidbody.mass * personalNormal);
}
Rotating your character and changing his normal is then up to you to suit your situation or game mechanic, whether you do that by raycasting if you're standing on a surface to detect when to change it or only want gravity to change when you hit a powerup or similar - experiment and see what works. Comment more if you have questions!
EDIT:
As an addition to the video you linked. You can keep a state variable on the jump state and raycast in each axis direction to check which face is nearest in the case of just rolling off.
public void Update()
{
// we don't update personal normals in the case of jumping
if(!jumping)
{
UpdatePersonalNormal();
}
}
public void UpdatePersonalNormal()
{
RaycastHit hit; //hit register
// list of valid normals to check (all 6 axis)
Ray[] rays =
{
Vector3.up, Vector3.down,
Vector3.left, Vector3.right,
Vector3.forward, Vector3.backward
};
//for each valid normal...
foreach(Ray rayDirection in rays)
{
//check if we are near a cube face...
if(Physics.Raycast(rayDirection , hit, normalSwitchRange)
{
personalNormal = hit.Normal; //set personal normal ...
return; // and return as we are done
}
}
}
Please keep in mind that the above is completely hand written and not tested but play with it and this pseudo start should give you a good idea of what to do.