I follow this tutorial
https://www.youtube.com/watch?v=SrCUO46jcxk
for multitouch, it work. And trying to add drag functionality on each object simultaneously with multiple finger.
This is my code for button i add some code to make it draggable each object simultaneously but it work on only single object. I tried all relevant post and tutorial but not able perform, please help??
using System.Collections;
using UnityEngine;
public class Button : MonoBehaviour{
public Color defaultColour;
public Color selectedColour;
private Material mat;
private Vector3 screenPoint;
private Vector3 offset;
void Start(){
mat = GetComponent<Renderer> ().material;
}
void OnTouchDown(){
mat.color = selectedColour;
Debug.Log ("Touch Down");
screenPoint = Camera.main.WorldToScreenPoint (transform.position);
offset = transform.position - Camera.main.ScreenToWorldPoint (new Vector3(Input.mousePosition.x, Input.mousePosition.y, screenPoint.z));
}
void OnTouchUp(){
mat.color = defaultColour;
Debug.Log ("Touch Up");
}
void OnTouchStay(){
mat.color = selectedColour;
Debug.Log ("Touch Stay");
Vector3 curScreenPoint = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + offset;
transform.position = curPosition;
}
void OnTouchExit(){
mat.color = defaultColour;
Debug.Log ("Touch Exit");
}
}
This code is for Input Touch functionality
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TouchInput : MonoBehaviour {
public LayerMask touchInputMask;
private static List<GameObject> touchList = new List<GameObject>();
private GameObject[] touchesOld;
private RaycastHit hit;
void Update () {
#if UNITY_EDITOR
if(Input.GetMouseButton(0) || Input.GetMouseButtonDown(0) || Input.GetMouseButtonUp(0)){
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit, touchInputMask)){
GameObject recipient = hit.transform.gameObject;
touchList.Add(recipient);
if (Input.GetMouseButtonDown(0)){
recipient.SendMessage("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButtonUp(0)){
recipient.SendMessage("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (Input.GetMouseButton(0)){
recipient.SendMessage("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
foreach (GameObject g in touchesOld){
if (!touchList.Contains(g)){
g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
}
#endif
if (Input.touchCount > 0){
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
foreach (Touch touch in Input.touches){
Ray ray = Camera.main.ScreenPointToRay (touch.position);
//RaycastHit hit;
if (Physics.Raycast(ray, out hit, touchInputMask)){
GameObject recipient = hit.transform.gameObject;
touchList.Add(recipient);
if (touch.phase == TouchPhase.Began){
recipient.SendMessage("OnTouchDown",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Ended){
recipient.SendMessage("OnTouchUp",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved){
recipient.SendMessage("OnTouchStay",hit.point,SendMessageOptions.DontRequireReceiver);
}
if (touch.phase == TouchPhase.Canceled){
recipient.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
}
foreach (GameObject g in touchesOld){
if (!touchList.Contains(g)){
g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
Now finally perform this process, i could perform this process in two ways
Using touchScript library, it has a rich feature we can drag, rotate, translate and scale multiple object in one time.
https://www.youtube.com/watch?v=HHLBJ1Ss2S0
Note: this is older video, now it changes but it is almost same.
[TouchScript is available in asset store for free]
other option, attach below code in empty gameobject or in camera(add tag layer)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public struct objectst {
public Vector3 screenPoint;
public Vector3 offset;
}
public class TouchInput : MonoBehaviour {
public LayerMask touchInputMask;
private static List<GameObject> touchList = new List<GameObject>();
public static Dictionary<int,objectst> touchobjects = new Dictionary<int,objectst>();
private GameObject[] touchesOld;
private RaycastHit hit;
public Text Count, IndexLift;
private Vector3 targetPos;
void Update () {
int nbTouches = Input.touchCount;
if(nbTouches > 0)
{
nbTouches = 5;
print(nbTouches + " touch(es) detected");
touchesOld = new GameObject[touchList.Count];
touchList.CopyTo(touchesOld);
touchList.Clear();
for (int i = 0; i < nbTouches ; i++)
{
Touch touch = Input.GetTouch(i);
print("Touch index " + touch.fingerId + " detected at position " + touch.position);
Ray ray = Camera.main.ScreenPointToRay (touch.position);
if (Physics.Raycast(ray, out hit, touchInputMask)){
GameObject recipient = hit.transform.gameObject;
touchList.Add(recipient);
//recipient.;
if (touch.phase == TouchPhase.Began){
objectst tempobj = new objectst ();
tempobj.screenPoint = Camera.main.WorldToScreenPoint (recipient.transform.position);
tempobj.offset = recipient.transform.position - Camera.main.ScreenToWorldPoint (new Vector3 (touch.position.x, touch.position.y, tempobj.screenPoint.z));
touchobjects.Add(touch.fingerId,tempobj);
}
if (touch.phase == TouchPhase.Stationary || touch.phase == TouchPhase.Moved){
Vector3 curScreenPoint = new Vector3 (touch.position.x, touch.position.y,
touchobjects[touch.fingerId].screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) + touchobjects[touch.fingerId].offset;
recipient.transform.position = curPosition;
}
if (touch.phase == TouchPhase.Ended){
Vector3 curScreenPoint = new Vector3 (touch.position.x, touch.position.y,
touchobjects[touch.fingerId].screenPoint.z);
Vector3 curPosition = Camera.main.ScreenToWorldPoint (curScreenPoint) - touchobjects[touch.fingerId].offset;
recipient.transform.position = curPosition;
}
if (touch.phase == TouchPhase.Canceled){
}
}
}
foreach (GameObject g in touchesOld){
if (!touchList.Contains(g)){
g.SendMessage("OnTouchExit",hit.point,SendMessageOptions.DontRequireReceiver);
}
}
}
}
}
Related
Here's the issue:
I have a raycast reflection that reflects normally, but when it encounters a straight wall it reflects in the X-Z plane.
I have it running (Code provided at the end of this explanation)
It looks like this:
Reflection Angle#01
Another: Reflection Angle#02
My main issue is making the bullets bounce according to my special laws of reflection, here's what I've been able to achieve by taking some help from code online:
Out of sync bullet.gif
As you can tell, the bullet is a bit skewed, I imagined it's because of the collision calculations since I turned off gravity and just use rigidbody.velocity to shoot these bullets, here's the code:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace StarterAssets
{
using UnityEngine;
public class CollisionDetector : MonoBehaviour
{
[SerializeField]
[Tooltip("Just for debugging, adds some velocity during OnEnable")]
private Vector3 initialVelocity;
[SerializeField]
private float minVelocity = 3f;
private Vector3 lastFrameVelocity;
private Rigidbody rb;
private void OnEnable()
{
transform.localScale = new Vector3(.5f, .5f, .5f);
rb = GetComponent<Rigidbody>();
rb.velocity = transform.forward * minVelocity;
}
private void Update()
{
lastFrameVelocity = rb.velocity;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Mirror"))
{
Bounce(collision.contacts[0].normal);
}
Physics.IgnoreCollision(collision.collider, GetComponent<Collider>());
}
private void Bounce(Vector3 collisionNormal)
{
rb.velocity = lastFrameVelocity;
var speed = lastFrameVelocity.magnitude;
Vector3 direction;
if (Mathf.Abs(collisionNormal.y) < .5)
{
var previousDirection = lastFrameVelocity.normalized;
previousDirection.y = 0;
var xzNormal = collisionNormal;
xzNormal.y = 0;
direction = Vector3.Reflect(previousDirection, xzNormal);
}
else
direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
Debug.Log("Out Direction: " + direction);
//rb.AddForce(direction * Mathf.Max(speed, minVelocity));
rb.velocity = direction * minVelocity;
}
}
}
Here's the code for the laser reflections:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
[RequireComponent(typeof(LineRenderer))]
public class RaycastReflection : MonoBehaviour
{
public int reflections;
public float maxLength;
private LineRenderer lineRenderer;
private Ray ray;
private RaycastHit hit;
//private Vector3 direction;
// Start is called before the first frame update
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
}
// Update is called once per frame
void Update()
{
ray = new Ray(transform.position, transform.forward);
//lineRenderer.material.color = Color.cyan;
lineRenderer.positionCount = 1;
lineRenderer.SetPosition(0, transform.position);
float remainingLength = maxLength;
for (int i = 0; i < reflections; i++)
{
if (Physics.Raycast(ray.origin, ray.direction, out hit, remainingLength,~(1 << 2)))
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, hit.point);
remainingLength -= Vector3.Distance(ray.origin, hit.point);
if(Mathf.Abs(hit.normal.y) <.5)
{
var previousDirection = ray.direction;
previousDirection.y = 0;
var xzNormal = hit.normal;
xzNormal.y = 0;
//var direction = Vector3.Reflect(previousDirection, xzNormal);
ray = new Ray(hit.point, Vector3.Reflect(previousDirection, xzNormal));
}
else
{
ray = new Ray(hit.point, Vector3.Reflect(ray.direction, hit.normal));
}
if (hit.collider.tag == "Totem")
{
//lineRenderer.material.color = new Color(0.4f, 0.9f, 0.7f, 1.0f);
break;
}
if (hit.collider.tag != "Mirror")
{
break;
}
}
else
{
lineRenderer.positionCount += 1;
lineRenderer.SetPosition(lineRenderer.positionCount - 1, ray.origin + ray.direction * remainingLength);
}
}
}
}
One of the easiest solutions I could think was to make the sphere/box collider extremely small, the collisions wouldnt cause a massive issue, and at slow speeds, this is true, it functions almost exactly like it's supposed to, but at higher speeds it's completely off the path again.
Another solution was to calculate the ray again from the cube, get the value of the hit.point reflections and put that inside the direction variable, use that to change my velocity each time,
Sadly doesn't work that conveniently
Here's my attempt:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace StarterAssets
{
using UnityEngine;
public class CollisionDetector : MonoBehaviour
{
[SerializeField]
[Tooltip("Just for debugging, adds some velocity during OnEnable")]
private Vector3 initialVelocity;
[SerializeField]
private float minVelocity = 2f;
private Vector3 lastFrameVelocity;
private Rigidbody rb;
private Ray ray;
private RaycastHit hit;
private void OnEnable()
{
ray = new Ray(transform.parent.parent.position, transform.parent.parent.forward);
Physics.Raycast(ray.origin, ray.direction, out hit, 20000, ~(1 << 2));
transform.localScale = new Vector3(.15f, .15f, .15f);
rb = GetComponent<Rigidbody>();
// rb.AddForce(ray.direction * minVelocity, ForceMode.Impulse);
rb.velocity = ray.direction * minVelocity;
}
private void Update()
{
lastFrameVelocity = rb.velocity;
}
private void OnCollisionEnter(Collision collision)
{
if (collision.gameObject.CompareTag("Mirror"))
{
Bounce(collision.contacts[0].normal);
}
else
Physics.IgnoreCollision(collision.collider, GetComponent<Collider>());
}
private void Bounce(Vector3 collisionNormal)
{
//var speed = lastFrameVelocity.magnitude;
Vector3 direction;
// transform.SetPositionAndRotation(hit.point, lastRotation);
transform.position = hit.point;
if (Mathf.Abs(hit.normal.y) < .5)
{
//var previousDirection = lastFrameVelocity.normalized;
//previousDirection.y = 0;
//var xzNormal = collisionNormal;
//xzNormal.y = 0;
//direction = Vector3.Reflect(previousDirection, xzNormal);
var previousDirection = ray.direction;
previousDirection.y = 0;
var xzNormal = hit.normal;
xzNormal.y = 0;
direction = Vector3.Reflect(previousDirection, xzNormal);
ray = new Ray(hit.point, direction);
}
else {
//direction = Vector3.Reflect(lastFrameVelocity.normalized, collisionNormal);
direction = Vector3.Reflect(ray.direction, hit.normal);
ray = new Ray(hit.point, direction);
}
Physics.Raycast(ray.origin, ray.direction, out hit, 20000, ~(1 << 2));
Debug.Log("Out Direction: " + direction);
//rb.AddForce(direction * Mathf.Max(speed, minVelocity));
//rb.velocity = direction * Mathf.Max(speed, minVelocity);
//rb.AddForce(direction * minVelocity, ForceMode.Impulse);
rb.velocity = direction * minVelocity;
}
}
I've also tried Vector3.MoveTowards and .Lerp, but I wasn't able to do it properly.
Please help! I have no idea how to make this darn bullet follow the laser path.
I have object that move around in fixed radius around another object with random height.
In this script i want the transform(turret) to rotate facing the target(target is the object that move with the random height) and that the laser that shoot will hit all the time the moving around target.
In the original i used the mouse to rotate the transform to be facing objects but now i want that the transform will rotate automatic to the moving target with the laser.
I added this part to the script and the laser start when running the game but the transform is not rotating facing the target. and i still can rotate the transform with the mouse and in this case i don't want the mouse to rotate the transform but that the transform will be rotating automatic.
if (startLaser)
{
Destroy(Instance);
Instance = Instantiate(Prefabs[Prefab], FirePoint.transform.position, FirePoint.transform.rotation);
Instance.transform.parent = transform;
LaserScript = Instance.GetComponent<Hovl_Laser>();
LaserScript2 = Instance.GetComponent<Hovl_Laser2>();
startLaser = false;
}
if (Cam != null)
{
RaycastHit hit;
RayMouse = Cam.ScreenPointToRay(target.position);
if(Physics.Raycast(RayMouse.origin, RayMouse.direction, out hit, MaxLength))
{
RotateToMouseDirection(gameObject, hit.point);
}
else
{
var pos = RayMouse.GetPoint(MaxLength);
RotateToMouseDirection(gameObject, pos);
}
}
but it's not working the transform is not rotating automatic and the mouse still controlling the rotating.
This is the full script :
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System;
using UnityEngine;
public class Hovl_DemoLasers : MonoBehaviour
{
public Transform target;
public GameObject FirePoint;
public Camera Cam;
public float MaxLength;
public GameObject[] Prefabs;
private Ray RayMouse;
private Vector3 direction;
private Quaternion rotation;
[Header("GUI")]
private float windowDpi;
private int Prefab;
private GameObject Instance;
private Hovl_Laser LaserScript;
private Hovl_Laser2 LaserScript2;
private bool rotateMouse = true;
private bool startLaser = true;
//Double-click protection
private float buttonSaver = 0f;
void Start ()
{
if (Screen.dpi < 1) windowDpi = 1;
if (Screen.dpi < 200) windowDpi = 1;
else windowDpi = Screen.dpi / 200f;
Counter(0);
}
void Update()
{
//Enable lazer
if (Input.GetMouseButtonDown(0))
{
Destroy(Instance);
Instance = Instantiate(Prefabs[Prefab], FirePoint.transform.position, FirePoint.transform.rotation);
Instance.transform.parent = transform;
LaserScript = Instance.GetComponent<Hovl_Laser>();
LaserScript2 = Instance.GetComponent<Hovl_Laser2>();
rotateMouse = true;
}
if (Input.GetMouseButtonDown(1))
{
rotateMouse = false;
}
//To change lazers
if ((Input.GetKey(KeyCode.A) || Input.GetAxis("Horizontal") < 0) && buttonSaver >= 0.4f)// left button
{
buttonSaver = 0f;
Counter(-1);
}
if ((Input.GetKey(KeyCode.D) || Input.GetAxis("Horizontal") > 0) && buttonSaver >= 0.4f)// right button
{
buttonSaver = 0f;
Counter(+1);
}
buttonSaver += Time.deltaTime;
if (startLaser)
{
Destroy(Instance);
Instance = Instantiate(Prefabs[Prefab], FirePoint.transform.position, FirePoint.transform.rotation);
Instance.transform.parent = transform;
LaserScript = Instance.GetComponent<Hovl_Laser>();
LaserScript2 = Instance.GetComponent<Hovl_Laser2>();
startLaser = false;
}
if (Cam != null)
{
RaycastHit hit;
RayMouse = Cam.ScreenPointToRay(target.position);
if(Physics.Raycast(RayMouse.origin, RayMouse.direction, out hit, MaxLength))
{
RotateToMouseDirection(gameObject, hit.point);
}
else
{
var pos = RayMouse.GetPoint(MaxLength);
RotateToMouseDirection(gameObject, pos);
}
}
//Current fire point
if (Cam != null && rotateMouse)
{
RaycastHit hit;
var mousePos = Input.mousePosition;
RayMouse = Cam.ScreenPointToRay(mousePos);
if (Physics.Raycast(RayMouse.origin, RayMouse.direction, out hit, MaxLength))
{
RotateToMouseDirection(gameObject, hit.point);
}
else
{
var pos = RayMouse.GetPoint(MaxLength);
RotateToMouseDirection(gameObject, pos);
}
}
else
{
Debug.Log("No camera");
}
}
//GUI Text
void OnGUI()
{
GUI.Label(new Rect(10 * windowDpi, 5 * windowDpi, 400 * windowDpi, 20 * windowDpi), "Use the keyboard buttons A/<- and D/-> to change lazers!");
GUI.Label(new Rect(10 * windowDpi, 20 * windowDpi, 400 * windowDpi, 20 * windowDpi), "Use left mouse button for shooting!");
}
//To change prefabs (count - prefab number)
void Counter(int count)
{
Prefab += count;
if (Prefab > Prefabs.Length - 1)
{
Prefab = 0;
}
else if (Prefab < 0)
{
Prefab = Prefabs.Length - 1;
}
}
//To rotate fire point
void RotateToMouseDirection (GameObject obj, Vector3 destination)
{
direction = destination - obj.transform.position;
rotation = Quaternion.LookRotation(direction);
obj.transform.localRotation = Quaternion.Lerp(obj.transform.rotation, rotation, 1);
}
}
This is working fine : I'm not sure if i need to use the out hit variable in the Automatic aiming part ? do i need to use the hit variable and if so how ?
// Automatic aiming part
if (Cam != null)
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, MaxLength))
{
RotateToMouseDirection(gameObject, target.position);
}
}
Anyway it's not working as i wanted.
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System;
using UnityEngine;
public class Hovl_DemoLasers : MonoBehaviour
{
public Transform target;
public GameObject FirePoint;
public Camera Cam;
public float MaxLength;
public GameObject[] Prefabs;
private Ray RayMouse;
private Ray AutomaticRay;
private Vector3 direction;
private Quaternion rotation;
[Header("GUI")]
private float windowDpi;
private int Prefab;
private GameObject Instance;
private Hovl_Laser LaserScript;
private Hovl_Laser2 LaserScript2;
private bool rotateMouse = true;
private bool startLaser = true;
//Double-click protection
private float buttonSaver = 0f;
void Start ()
{
//LaserEndPoint = new Vector3(0, 0, 0);
if (Screen.dpi < 1) windowDpi = 1;
if (Screen.dpi < 200) windowDpi = 1;
else windowDpi = Screen.dpi / 200f;
Counter(0);
}
void Update()
{
//Enable lazer
if (Input.GetMouseButtonDown(0))
{
Destroy(Instance);
Instance = Instantiate(Prefabs[Prefab], FirePoint.transform.position, FirePoint.transform.rotation);
Instance.transform.parent = transform;
LaserScript = Instance.GetComponent<Hovl_Laser>();
LaserScript2 = Instance.GetComponent<Hovl_Laser2>();
rotateMouse = true;
}
if (Input.GetMouseButtonDown(1))
{
rotateMouse = false;
}
//Disable lazer prefab
if (Input.GetMouseButtonUp(0))
{
/*if (LaserScript) LaserScript.DisablePrepare();
if (LaserScript2) LaserScript2.DisablePrepare();
Destroy(Instance,1);*/
}
//To change lazers
if ((Input.GetKey(KeyCode.A) || Input.GetAxis("Horizontal") < 0) && buttonSaver >= 0.4f)// left button
{
buttonSaver = 0f;
Counter(-1);
}
if ((Input.GetKey(KeyCode.D) || Input.GetAxis("Horizontal") > 0) && buttonSaver >= 0.4f)// right button
{
buttonSaver = 0f;
Counter(+1);
}
buttonSaver += Time.deltaTime;
if (startLaser)
{
rotateMouse = false;
Destroy(Instance);
Instance = Instantiate(Prefabs[Prefab], FirePoint.transform.position, FirePoint.transform.rotation);
Instance.transform.parent = transform;
LaserScript = Instance.GetComponent<Hovl_Laser>();
LaserScript2 = Instance.GetComponent<Hovl_Laser2>();
startLaser = false;
}
// Automatic aiming part
if (Cam != null)
{
RaycastHit hit;
if (Physics.Raycast(transform.position, transform.TransformDirection(Vector3.forward), out hit, MaxLength))
{
RotateToMouseDirection(gameObject, target.position);
}
}
//Current fire point
if (Cam != null && rotateMouse)
{
RaycastHit hit; //DELATE THIS IF YOU WANT TO USE LASERS IN 2D
var mousePos = Input.mousePosition;
RayMouse = Cam.ScreenPointToRay(mousePos);
//ADD THIS IF YOU WANT TO USE LASERS IN 2D: RaycastHit2D hit = Physics2D.Raycast(RayMouse.origin, RayMouse.direction, MaxLength);
if (Physics.Raycast(RayMouse.origin, RayMouse.direction, out hit, MaxLength)) //CHANGE THIS IF YOU WANT TO USE LASERRS IN 2D: if (hit.collider != null)
{
RotateToMouseDirection(gameObject, hit.point);
}
else
{
var pos = RayMouse.GetPoint(MaxLength);
RotateToMouseDirection(gameObject, pos);
}
}
else
{
Debug.Log("No camera");
}
}
//GUI Text
void OnGUI()
{
GUI.Label(new Rect(10 * windowDpi, 5 * windowDpi, 400 * windowDpi, 20 * windowDpi), "Use the keyboard buttons A/<- and D/-> to change lazers!");
GUI.Label(new Rect(10 * windowDpi, 20 * windowDpi, 400 * windowDpi, 20 * windowDpi), "Use left mouse button for shooting!");
}
//To change prefabs (count - prefab number)
void Counter(int count)
{
Prefab += count;
if (Prefab > Prefabs.Length - 1)
{
Prefab = 0;
}
else if (Prefab < 0)
{
Prefab = Prefabs.Length - 1;
}
}
//To rotate fire point
void RotateToMouseDirection (GameObject obj, Vector3 destination)
{
direction = destination - obj.transform.position;
rotation = Quaternion.LookRotation(direction);
obj.transform.localRotation = Quaternion.Lerp(obj.transform.rotation, rotation, 1);
}
}
I have a script which fires a linerenderer from a start to end position with each click. I want to have a linerender that is constant until the mouse button is released. Like a power charge. What do I need to add in the script to make this happen?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RayCastShot : MonoBehaviour
{
public float fireRate = 0.25f;
public float weaponRange = 50f;
public float hitForce = 100f;
public Transform gunEndLeft;
public Transform gunEndRight;
private Camera fpsCam;
private WaitForSeconds shotDuration = new WaitForSeconds(0.07f);
private LineRenderer lineRenderer;
private float nextFire;
public Material mat1;
public Material mat2;
void Start()
{
lineRenderer = GetComponent<LineRenderer>();
fpsCam = GetComponent<Camera>();
}
void Update()
{
if (Input.GetButtonDown("Fire1") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndLeft.position);
lineRenderer.material = mat1;
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if(hit.rigidbody !=null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
if (Input.GetButtonDown("Fire2") && Time.time > nextFire)
{
nextFire = Time.time + fireRate;
StartCoroutine(ShotEffect());
Vector3 rayOrigin = fpsCam.ViewportToWorldPoint(new Vector3(0.5f, 0.5f, 0.0f));
RaycastHit hit;
lineRenderer.SetPosition(0, gunEndRight.position);
lineRenderer.material = mat2;
//lineRenderer.material = new Material(Shader.Find("Particles/Priority Additive"));
if (Physics.Raycast(rayOrigin, fpsCam.transform.forward, out hit, weaponRange))
{
lineRenderer.SetPosition(1, hit.point);
//get reference to hit point
}
if (hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * hitForce);
}
else
{
lineRenderer.SetPosition(1, rayOrigin + (fpsCam.transform.forward * weaponRange));
}
}
}
private IEnumerator ShotEffect()
{
lineRenderer.enabled = true;
yield return shotDuration;
lineRenderer.enabled = false;
}
}
Well you can start by use Input.GetButtonUp to stop the fire.
That way you can start on Input.GetButtonDown and stop only when buttonUp.
If you need to execute code every frame you can also use Input.GetButton.
That's the basic idea.
I made an AI Enemy system that has the enemy walk towards a target that I want to attack.The target (who is the player collects points). What I want is when the enemy reaches its target it takes away -1 point from the player. What I want to know is how do I deduct the point from my game manager. I already created a public game object that carries the script for my points. When I try this out the enemy does not take a point away once it reaches the player. Should I create a function within my Enemy AI script called TargetIsReached()?
public class aiEnemy : MonoBehaviour, IPooledObject {
public float lookRadius = 40f;
Transform target;
UnityEngine.AI.NavMeshAgent agent;
Rigidbody theRigidBody;
public Casting castingScript;
void Start(){
target = PlayerManager.instance.player.transform;
agent = GetComponent<UnityEngine.AI.NavMeshAgent>();
}
void Update(){
float distance = Vector3.Distance (target.position, transform.position);
if (distance <= lookRadius)
{
agent.SetDestination (target.position);
if (distance <= agent.stoppingDistance)
{
FaceTarget ();
castingScript.RemovePoint ();
}
}
}
void FaceTarget()
{
Vector3 direction = (target.position - transform.position).normalized;
Quaternion lookRotation = Quaternion.LookRotation (new Vector3 (direction.x, 0, direction.z));
transform.rotation = Quaternion.Slerp (transform.rotation, lookRotation, Time.deltaTime * 5f);
}
// Use this for initialization
public void OnObjectSpawn () {
//myRender = GetComponent<Renderer> ();
theRigidBody = GetComponent<Rigidbody>();
}
void OnDrawGizmosSelected()
{
Gizmos.color = Color.red;
Gizmos.DrawWireSphere (transform.position, lookRadius);
}
}
//Casting Script//
public GameObject Float;
public Transform target;
public GameObject disableFish;
public float waitTime= 3f;
public int scoreValue = 1;
int waterMask;
public float maxCastDist = 1000f;
public float fishDist = 1f;
public bool hitObject;
void Awake ()
{
waterMask = LayerMask.GetMask ("Water"); // will only cast in water
}
void Update ()
{
if (EventSystem.current.IsPointerOverGameObject ()) {
return;
} else {
if (Input.GetMouseButtonDown (0)) {
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit, maxCastDist, waterMask))
if (hit.collider != null) {
float dist = Vector3.Distance (hit.point, target.position);
Debug.Log (dist);
Destroy (GameObject.FindWithTag ("Float"));
Instantiate (Float, hit.point, Quaternion.identity);
if (dist < fishDist) {
disableFish.SetActive(false);
StartCoroutine (fishWaiter ());
StartCoroutine (DestroyOb(waitTime));
}
}
}
}
}
IEnumerator fishWaiter ()
{
FishLoader.SetActive (true);
FishSlider.value = waitTime;
Debug.Log ("Timer Started");
yield return new WaitForSeconds (waitTime);
print ("I waited" + waitTime + "Sec");
FishSlider.value = 0f;
print ("You Caught The Fish!");
ScoreManager.score += scoreValue;
}
IEnumerator DestroyOb (float waitTime){
yield return new WaitForSeconds (waitTime);
Destroy (GameObject.FindWithTag ("Float"));
}
}
Hello and thanks for reading this post.
I have 2 objects: A player Object and a JumpButton Object.
The Player object is the player. ofc. The JumpButton Object is an object that I want to make the player jump when you use a touch screen device aka android phone.
This is my Script that is assinged to my JumpButton: using UnityEngine; using System.Collections;
using UnityEngine;
using System.Collections;
public class JumpButtonScript : MonoBehaviour {
public GameObject player;
public GameObject JumpButton;
// Use this for initialization
void Start () {
player = GameObject.Find ("player");
}
// Update is called once per frame
void Update () {
if ((Input.touchCount == 1) && (Input.GetTouch(0).phase == TouchPhase.Began))
{
}
}
}
This is the script that allows me to control the player with arrow keys.
using UnityEngine;
using System.Collections;
public class RobotController : MonoBehaviour {
//This will be our maximum speed as we will always be multiplying by 1
public float maxSpeed = 2f;
public GameObject player;
public GameObject sprite;
//a boolean value to represent whether we are facing left or not
bool facingLeft = true;
//a value to represent our Animator
Animator anim;
//to check ground and to have a jumpforce we can change in the editor
bool grounded = true;
public Transform groundCheck;
public float groundRadius = 1f;
public LayerMask whatIsGround;
public float jumpForce = 300f;
private bool isOnGround = false;
void OnCollisionEnter2D(Collision2D collision) {
isOnGround = true;
}
void OnCollisionExit2D(Collision2D collision) {
anim.SetBool ("Ground", grounded);
anim.SetFloat ("vSpeed", rigidbody2D.velocity.y);
isOnGround = false;
}
// Use this for initialization
void Start () {
player = GameObject.Find("player");
//set anim to our animator
anim = GetComponent <Animator>();
}
void FixedUpdate () {
//set our vSpeed
//set our grounded bool
grounded = Physics2D.OverlapCircle (groundCheck.position, groundRadius, whatIsGround);
//set ground in our Animator to match grounded
anim.SetBool ("Ground", grounded);
float move = Input.GetAxis ("Horizontal");//Gives us of one if we are moving via the arrow keys
//move our Players rigidbody
rigidbody2D.velocity = new Vector3 (move * maxSpeed, rigidbody2D.velocity.y);
//set our speed
anim.SetFloat ("Speed",Mathf.Abs (move));
//if we are moving left but not facing left flip, and vice versa
if (move > 0 && !facingLeft) {
Flip ();
} else if (move < 0 && facingLeft) {
Flip ();
}
}
void Update(){
if ((isOnGround == true && Input.GetKeyDown (KeyCode.UpArrow)) || (isOnGround == true && Input.GetKeyDown (KeyCode.Space))) {
anim.SetBool("Ground",false);
rigidbody2D.AddForce (new Vector2 (0, jumpForce));
}
if (isOnGround == true && Input.GetKeyDown (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.2f, 0.2f);
}
if (isOnGround == true && Input.GetKeyUp (KeyCode.DownArrow))
{
gameObject.transform.localScale = new Vector3(transform.localScale.x, 0.3f, 0.3f);
}
}
//flip if needed
void Flip(){
facingLeft = !facingLeft;
Vector3 theScale = transform.localScale;
theScale.x *= -1;
transform.localScale = theScale;
}
}
As you can see, then I managed to make the player move on arrow keys, but how can I make it jump when I hit the jump button (touch Screen press), as on an Android Phone?
I really hope you can help me.
If your problem is how to handle input, try this code we will make ray from camera to mousepos in screen and check tag to see what we hitted
public class handleInput: MonoBehaviour {
void Update () {
if (Input.GetMouseButtonDown (0)) {
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit)) {
if (hit.collider.tag=="jumpbutton"){
jump();
}
}
}
}
}
and for the jumping part you can do this , adding a force to player to send him up and gravity should pull him down
if (grounded == true)
{
rigidbody.AddForce(Vector3.up* jumpSpeed);
grounded = false;
}