Shooting prefab according to cannon angle with projection - unity3d

This code shoots at the mouse pointer but goes directly, not by projection. I need it to be like the picture below.
var prefab : GameObject;
function Update () {
if (Input.GetMouseButtonDown(0)) {
var pos = Input.mousePosition;
pos.z = transform.position.z - Camera.main.transform.position.z;
pos = Camera.main.ScreenToWorldPoint(pos);
var q = Quaternion.FromToRotation(Vector3.up, pos - transform.position);
var go = Instantiate(prefab, transform.position, q);
go.rigidbody2D.AddForce(go.transform.up * 20000.0);
}
}

Related

Angle information(degree) between AR camera and target object on a plane

I have a question, please help and thanks!
I want to know how to show the Angle information(degree) between AR camera and target object on a plane. (Using Smartphone)
And I want to know how to "code" with Unity and AR Foundation.
I tried using some code(below), but it seems only work on Distance, not work on Angle...
Thank again!
void Start ()
{
//get the components
private ARRaycastManager RayManager;
private GameObject visual;
public Camera CameraStart;
public Text textField2;
public Text textField;
float distance;
float angle;
RayManager = FindObjectOfType<ARRaycastManager>();
visual = transform.GetChild(0).gameObject;
}
void Update ()
{
// shoot a raycast from the center of the screen
List<ARRaycastHit> hits = new List<ARRaycastHit>();
RayManager.Raycast(new Vector2(Screen.width / 2, Screen.height / 2), hits, TrackableType.Planes);
RaycastHit hit;
//Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
// check if we hit an AR plane, update the position and rotation
if(hits.Count > 0)
{
transform.position = hits[0].pose.position;
transform.rotation = hits[0].pose.rotation;
distance = Vector3.Distance(CameraStart.transform.position, transform.position);
textField.text = distance.ToString("N2") + "meter";
Physics.Raycast(transform.position, out hit);
angle = Vector3.Angle(hit.normal, transform.forward);
textField2.text = angle.ToString("N2") + "degree";
if(!visual.activeInHierarchy)
visual.SetActive(true);
}
}
}
I would check that the ray hits:
if (Physics.Raycast(transform.position, out hit)) {
angle = Vector3.Angle(hit.normal, transform.forward);
textField2.text = angle.ToString("N2") + "degree";
} else {
Debug.LogError("Did not hit")
}
Also I would make sure that the target has a collider and that the layer mask is correct.

Using RayCastAll instead of RayCast

I have two gameobjects roller and marker. When I use physics raycast it works, but with raycastall it doesn't. I need to use raycastall, because i need to iterate through colliders. When marker is on roller normal raycast doesn't work and I need to use raycastall.
This code works:
if (Input.touchCount > 0)
{
// get mouse position in screen space
// (if touch, gets average of all touches)
Vector3 screenPos = Input.mousePosition;
// set a distance from the camera
screenPos.z = 10.0f;
// convert mouse position to world space
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
Physics.Raycast(cameraRay, out hit);
if (hit.collider.tag == "Floor")
{
transform.position = hit.point;
}
/*
Vector3 worldPos = Camera.main.ScreenToWorldPoint(screenPos);
// get current position of this GameObject
Vector3 newPos = transform.position;
// set x position to mouse world-space x position
newPos.x = worldPos.x;
newPos.z = worldPos.z-3f;
// apply new position
transform.position = newPos;
*/
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
Destroy(gameObject);
touchhandler = GameObject.Find("Roller").GetComponent<TouchHandler>();
touchhandler.markerexists = false;
}
}
And this doesn't:
if (Input.touchCount > 0)
{
// get mouse position in screen space
// (if touch, gets average of all touches)
Vector3 screenPos = Input.mousePosition;
// set a distance from the camera
screenPos.z = 10.0f;
// convert mouse position to world space
Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit[] hits;
hits = Physics.RaycastAll(Camera.main.ScreenPointToRay(Input.mousePosition), 100.0F);
while (i < hits.Length)
{
RaycastHit hit = hits[i];
if (hit.collider.tag == "Floor")
{
transform.position = hit.point;
}
i++;
}
if (Input.GetTouch(0).phase == TouchPhase.Ended)
{
Destroy(gameObject);
touchhandler = GameObject.Find("Roller").GetComponent<TouchHandler>();
touchhandler.markerexists = false;
}
}

How to make a rigid body object you're carrying not go through walls?

I have a player who can carry objects with its gun in a "2.5D Platform Shooter" game but the problem I'm experiencing at the moment is that every time I make the player hold the object(it has a rigid body) and pressed against the wall, the object goes through the wall. Please help unity fans.
This the code I'm using below to carry the object.
#pragma strict
var catchRange = 30.0;
var holdDistance = 4.0;
var minForce = 1000;
var maxForce = 10000;
var forceChargePerSec = 3000;
var layerMask : LayerMask = -1;
#HideInInspector
var anim : Animator;
enum GravityGunState { Free, Catch, Occupied, Charge, Release};
private var gravityGunState : GravityGunState = 0;
private var rigid : Rigidbody = null;
private var currentForce = minForce;
function FixedUpdate()
{
if(gravityGunState == GravityGunState.Free)
{
if(Input.GetButton("Fire1"))
{ anim.SetBool("Shoot", true);
var hit : RaycastHit;
if(Physics.Raycast(transform.position, transform.forward, hit, catchRange, layerMask))
{
if(hit.rigidbody)
{
rigid = hit.rigidbody;
gravityGunState = GravityGunState.Catch;
}
}
}else if(!hit.rigidbody){anim.SetBool("Shoot", false);}
}
else if(gravityGunState == GravityGunState.Catch)
{
rigid.useGravity = false;
rigid.MovePosition(transform.position + transform.forward * holdDistance);
if(!Input.GetButton("Fire1"))
gravityGunState = GravityGunState.Occupied;
}
else if(gravityGunState == GravityGunState.Occupied)
{
if(Physics.Raycast(transform.position, transform.forward, hit, catchRange, layerMask)){
Debug.DrawLine (transform.position, hit.point, Color.red);
}
rigid.MovePosition(transform.position + transform.forward * holdDistance);
if(Input.GetButton("Fire1"))
gravityGunState = GravityGunState.Charge;
}
else if(gravityGunState == GravityGunState.Charge)
{
rigid.MovePosition(transform.position + transform.forward * holdDistance);
if(currentForce < maxForce)
{
currentForce += forceChargePerSec * Time.deltaTime;
}
else
{
currentForce = maxForce;
}
if(!Input.GetButton("Fire1"))
gravityGunState = GravityGunState.Release;
rigid.useGravity = true;
}
else if(gravityGunState == GravityGunState.Release)
{
rigid.AddForce(transform.forward * currentForce);
currentForce = minForce;
gravityGunState = GravityGunState.Free;
}
}
#script ExecuteInEditMode()
adding collider to gameObjects will prevent object from moving through each other and if it already has a collider and it is passing through check your settings as follows
Rigidbody Is Kinamatic : False, Is Triggger:false
set the Collision Detection of rigidbody to Continuous or Continuous Dynamic
sometimes for fast moving game objects the collision wont be detected in these sceneraios you can use Raycasting for collisin detection here is DontGoThrough Script that use raycasting for collision detection
using UnityEngine;
using System.Collections;
public class DontGoThroughThings : MonoBehaviour
{
public LayerMask layerMask; //make sure we aren't in this layer
public float skinWidth = 0.1f; //probably doesn't need to be changed
private float minimumExtent;
private float partialExtent;
private float sqrMinimumExtent;
private Vector3 previousPosition;
private Rigidbody myRigidbody;
//initialize values
void Awake()
{
myRigidbody = rigidbody;
previousPosition = myRigidbody.position;
minimumExtent = Mathf.Min(Mathf.Min(collider.bounds.extents.x, collider.bounds.extents.y), collider.bounds.extents.z);
partialExtent = minimumExtent * (1.0f - skinWidth);
sqrMinimumExtent = minimumExtent * minimumExtent;
}
void FixedUpdate()
{
//have we moved more than our minimum extent?
Vector3 movementThisStep = myRigidbody.position - previousPosition;
float movementSqrMagnitude = movementThisStep.sqrMagnitude;
if (movementSqrMagnitude > sqrMinimumExtent)
{
float movementMagnitude = Mathf.Sqrt(movementSqrMagnitude);
RaycastHit hitInfo;
//check for obstructions we might have missed
if (Physics.Raycast(previousPosition, movementThisStep, out hitInfo, movementMagnitude, layerMask.value))
myRigidbody.position = hitInfo.point - (movementThisStep/movementMagnitude)*partialExtent;
}
previousPosition = myRigidbody.position;
}
}

Unable to change rotation in Unity3D

I've been working on a project in Unity3D and found a javascript that makes the enemies follow the player. This is the script:
var target : Transform; //the enemy's target
var moveSpeed = 3; //move speed
var rotationSpeed = 3; //speed of turning
var myTransform : Transform; //current transform data of this enemy
function Awake()
{
myTransform = transform; //cache transform data for easy access/preformance
}
function Start()
{
target = GameObject.FindWithTag("Player").transform; //target the player
}
function Update () {
//rotate to look at the player
myTransform.rotation = Quaternion.Slerp(myTransform.rotation,
Quaternion.LookRotation(target.position - myTransform.position), rotationSpeed*Time.deltaTime);
//move towards the player
myTransform.position += myTransform.forward * moveSpeed * Time.deltaTime;
}
When the enemies "rotate to look at the player" they rotate from a horizontal position to a vertical. How can I change the script in order to prevent that from happening?
You have a secon parameter at Quaternion.LookRotation
You may use :
Quaternion.LookRotation(target.position - myTransform.position, Vector3.up)
or
Quaternion.LookRotation(target.position - myTransform.position, transform.up)

How to get projectile to move in the direction the player is facing

This is the code for my player's movement:
var animator : Animator;
function Start () {
animator = GetComponent("Animator");
}
var moveUp : KeyCode;
var moveDown : KeyCode;
var moveLeft : KeyCode;
var moveRight : KeyCode;
var jumpheight : int = 2;
var speed : int = 2;
var isGrounded : int = 0;
// Checks if player is in air or ground
var Jumptest : int = 0;
// Checks if player has jumped
function Update () {
animator.SetInteger("Direction", 4);
if (Input.GetKey(moveUp) && isGrounded == 0)
{
rigidbody2D.velocity.y = jumpheight;
isGrounded = 1;
animator.SetInteger("Direction", 2);
}
else if (Input.GetKey(moveLeft))
{
transform.position += Vector3.left * speed * Time.deltaTime;
animator.SetInteger("Direction", 3);
}
else if (Input.GetKey(moveRight))
{
transform.position += Vector3.right * speed * Time.deltaTime;
animator.SetInteger("Direction", 1);
}
}
and this is the code for the projectiles movement:
#pragma strict
var speed = 8.0;
var time = 0.0;
function Start () {
}
var moveRight : KeyCode;
var moveLeft : KeyCode;
function Update () {
time += Time.deltaTime;
if(time > 3){
Destroy(gameObject);
}
transform.Translate(Vector3.right * speed * Time.deltaTime, Space.Self);
}
At the moment, the projectiles shoot to the right. I want to be able to shoot them in the direction the player is facing.
I tried if key down a and if key down d but then the projectiles stop when the player is not moving and move relative to the player (if I shoot one going left, then move my player to the right, the projectile reverses direction).
Anybody know?
When checking for player movement , whether the left/right key is down, you create a simple integer which keeps track of direction
...
var isRight: int=1 ;//assuming player starts with facing in the right direction
...
and then, when checking for key press set the value of this variable appropriately
...
else if (Input.GetKey(moveLeft)&&!Input.GetKey(moveRight))
{
isRight = -1;
...
}
else if (Input.GetKey(moveRight)&&!Input.GetKey(moveLeft))
{
isRight = 1;
...
}
Finally when setting translation for the projectile simply multiply the speed with this new variable
transform.Translate(Vector3.right * speed * isRight * Time.deltaTime, Space.Self);