Power charge shot while holding mousebuttondown - c#

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.

Related

How to make an object follow a special raycast reflection?

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.

How can i make object to rotate smooth towards a target with raycast?

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);
}
}

Auto shoot script for VR? (changing Script)

I am integrating my game to VR and now i wanted to change my controlling. In the script given bellow when the player press the mouse button the gun fires the bullet but now in VR i don't want my game to be controlled by any controller. what i want is when player moves his head and the focus point comes to the Enemy it starts shooting without pressing any button(I mean auto shoot). what should i do??
grausing System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GunScript : MonoBehaviour {
public float damage = 10f;
public float range = 100f;
public float fireRate = 15f;
public float impactForce = 30f;
public Camera fpsCam;
public GameObject impactEffect;
private float nextTimeToFire = 0f;
// Update is called once per frame
void Update () {
if (Input.GetButton("Fire1") && Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}
void Shoot()
{
RaycastHit hit;
if (Physics.Raycast(fpsCam.transform.position, fpsCam.transform.forward, out hit, range))
{
Debug.Log(hit.transform.name);
Target target = hit.transform.GetComponent<Target>();
if (target != null)
{
target.TakeDamage(damage);
}
if(hit.rigidbody != null)
{
hit.rigidbody.AddForce(-hit.normal * impactForce);
}
GameObject ImpactEffectGO = Instantiate(impactEffect, hit.point, Quaternion.LookRotation(hit.normal));
Destroy(ImpactEffectGO, 2f);
}
}
}
Since you already have an existing shooting mechanic, simply changing up the Update() should do what you want
void Update () {
if (Time.time >= nextTimeToFire)
{
nextTimeToFire = Time.time + 1f / fireRate;
Shoot();
}
}

Point deduction from enemy once target is reached?

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"));
}
}

Drag different object simultaneously with multiple finger

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);
}
}
}
}
}

Categories

Resources