Reputation: 11329
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OnMouseOverEvent : MonoBehaviour
{
public float duration;
public string tag;
public Vector3 startPos;
public Vector3 endPos;
public float distancetoMove = 1f;
public float lerpTime = 5;
private float currentLerpTime = 0;
private void Start()
{
startPos = transform.position;
endPos = transform.position - Vector3.forward * distancetoMove;
}
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
if (hit.transform.tag == tag)
{
currentLerpTime += Time.deltaTime;
if(currentLerpTime >= lerpTime)
{
currentLerpTime = lerpTime;
}
float Perc = currentLerpTime / lerpTime;
transform.position = Vector3.Lerp(startPos, endPos, Perc);
}
else
{
transform.position = Vector3.Lerp(endPos, startPos, Perc);
}
}
}
}
If it's hitting the object is moving smooth slowly forward but I want that while the raycast keep hitting the object it will move forward and if got to the distance keep it stay there as long as the raycast hitting it.
But once moving the mouse and the raycast is not hitting the object either in the middle of the movement or when it got to the distance move the object back to it's start position.
So when moving the mouse out of the object area it will start moving either forward to endPos or backward to startPos.
Upvotes: 1
Views: 145
Reputation: 7
Another way to do it: (Without Raycast)
using UnityEngine;
public class Move : MonoBehaviour
{
public float speed = 5f;
public float distancetoMove = 1f;
public bool goForward;
public Vector3 startPos;
public Vector3 endPos;
private void Start()
{
startPos = transform.position;
endPos = transform.position - Vector3.forward * distancetoMove;
}
void Update()
{
if (goForward)
{
transform.position = Vector3.MoveTowards(transform.position, endPos, speed * Time.deltaTime);
}
else
{
transform.position = Vector3.MoveTowards(transform.position, startPos, speed * Time.deltaTime);
}
}
private void OnMouseOver()
{
goForward = true;
}
private void OnMouseExit()
{
goForward = false;
}
}
you have to declare Perc outsdide if
if you want to use ot inside else
to solve your problem
change:
inside if (hit.transform.tag == tag)
transform.position = Vector3.Lerp(start, endPos, Perc);
to this:
transform.position = Vector3.Lerp(transform.position, endPos, Perc);
and inside else
else{
transform.position = Vector3.Lerp(endPos, startPos, Perc);
}
to this:
else{
transform.position = Vector3.Lerp(transform.position, startPos, Perc);
}
your code will become like this:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class OnMouseOverEvent : MonoBehaviour
{
public float duration;
public string tag;
public Vector3 startPos;
public Vector3 endPos;
public float distancetoMove = 1f;
public float lerpTime = 5;
float Perc;
private float currentLerpTime = 0;
private void Start()
{
startPos = transform.position;
endPos = transform.position - Vector3.forward * distancetoMove;
}
private void Update()
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
if (hit.transform.tag == tag)
{
currentLerpTime += Time.deltaTime;
if (currentLerpTime >= lerpTime)
{
currentLerpTime = lerpTime;
}
Perc = currentLerpTime / lerpTime;
transform.position = Vector3.Lerp(transform.position, endPos, Perc);
}
else
{
transform.position = Vector3.Lerp(transform.position, startPos, Perc);
}
}
}
}
Upvotes: 1
Reputation: 4046
Perc
) not updating properlyYour object currently moves in the update by a Lerp
, which the interpolant is Perc
.
The problem is that your code for updating your Perc
by lerp timer is only done when the raycast hits this object.
You can update your Perc
by lerp-timer before/after you done the movement process, like so:
private float Perc;
private void Update()
{
GetPercByLerpTime(); // Update before it moves
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100))
{
if (hit.transform.tag == tag)
{
transform.position = Vector3.Lerp(startPos, endPos, Perc);
}
else
{
transform.position = Vector3.Lerp(endPos, startPos, Perc);
}
}
// Or you can update your 'Perc' here.
}
private void UpdatePercByLerpTime(){
currentLerpTime += Time.deltaTime;
if(currentLerpTime >= lerpTime)
{
currentLerpTime = lerpTime;
}
Perc = currentLerpTime / lerpTime;
}
Note: You might notice that currentLerpTime
will keep incrementing until it reaches lerpTime
, and it will stay as the same value as lerpTime
.
You might want to implement something that either decreases or resets currentLerpTime
.
Your currently code only moves the object if the raycast hits something. (Though it does move in the correct direction depending if it hit this object)
What you probably want is to move the object back to the start position if the raycast hit nothing or the raycast hit something else.
So your final result would look like this:
private float Perc;
private void Update() {
UpdatePercByLerpTime();
if (MouseRaycastHitThisObject()) {
transform.position = Vector3.Lerp(startPos, endPos, Perc);
} else {
transform.position = Vector3.Lerp(endPos, startPos, Perc);
}
// Or you can update your 'Perc' here.
}
// True if the raycastfrom the mouse position hits this object
private bool MouseRaycastHitThisObject(){
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, 100)) {
return hit.transform.tag == tag;
}
// Raycast did not hit anything; Player's mouse is not hovering over anything.
return false;
}
private void UpdatePercByLerpTime(){
currentLerpTime += Time.deltaTime;
if(currentLerpTime >= lerpTime) {
currentLerpTime = lerpTime;
}
Perc = currentLerpTime / lerpTime;
}
Upvotes: 0