Rotating a bottle Unity3D - unity3d

I'm trying to spin a bottle (I'm calculating the first pos and end pos of the mouse) and apply forces to it according to the 'swipe' length/time. After the initial swipe, the bottle should keep rotating based on the force of the swipe, and then stop after few seconds.
I hope you could help me here. Thanks!
bottle interface
This is what I tried to do, but it doesn't work well:
public Rigidbody bottle;
bool isSwiping;
Touch thisTouch;
Vector2 origPos;
Vector2 endPos;
float touchSpeed;
Vector3 Torque;
float timeStart; float timeEnd;
void OnMouseDown()
{
timeStart = Time.time;
origPos = Input.mousePosition;
}
void OnMouseDrag()
{
isSwiping = true;
}
void OnMouseUp()
{
if (isSwiping)
{
timeEnd = Time.time;
endPos = Input.mousePosition;
Vector2 deltaPosition = endPos - origPos;
touchSpeed = deltaPosition.magnitude / (timeEnd-timeStart);
Torque = new Vector3(touchSpeed * 500f, 0, 0);
}
}
void Update()
{
}
void FixedUpdate()
{
if (isSwiping) bottle.AddRelativeTorque(Torque);
}

Try use this code:
public Rigidbody bottle;
bool isSwiping;
Touch thisTouch;
Vector2 origPos;
Vector2 endPos;
float touchSpeed;
Vector3 Torque;
float timeStart; float timeEnd;
void OnMouseDown()
{
timeStart = Time.time;
origPos = Input.mousePosition;
}
void OnMouseUp()
{
timeEnd = Time.time;
endPos = Input.mousePosition;
Vector2 deltaPosition = endPos - origPos;
touchSpeed = deltaPosition.magnitude / (timeEnd-timeStart);
Torque = new Vector3(touchSpeed * 500f, 0, 0);
isSwiping = true;
}
void FixedUpdate()
{
if (isSwiping) bottle.AddRelativeTorque(Torque);
}

Related

Why is UpdateJump not causing my character to jump

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
[SerializeField] Transform playerCamera = null;
[SerializeField] float xSensitivity = 4.0f;
[SerializeField] float ySensitivity = 4.0f;
[SerializeField] float moveSpeed = 6.0f;
[SerializeField] float gravity = -13.0f;
[SerializeField][Range(0.0f, 0.1f)] float moveSmoothTime = 0.05f;
[SerializeField][Range(0.0f, 0.2f)] float mouseSmoothTime = 0.03f;
[SerializeField] bool lockCursor = true;
float cameraPitch = 0.0f;
float velocityY = 0.0f;
CharacterController controller = null;
Vector2 currentDir = Vector2.zero;
Vector2 currentDirVelocity = Vector2.zero;
Vector2 currentMouseDelta = Vector2.zero;
Vector2 currentMouseDeltaVelocity = Vector2.zero;
public Vector3 jump;
public float jumpForce = 8.0f;
public bool isGrounded;
Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
jump = new Vector3(0.0f, 2.0f, 0.0f);
controller = GetComponent<CharacterController>();
if(lockCursor)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
}
// Update is called once per frame
void Update()
{
UpdateMouseLook();
UpdateMovement();
OnCollisionStay();
UpdateJump();
}
void UpdateMouseLook()
{
Vector2 targetMouseDelta = new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y"));
currentMouseDelta = Vector2.SmoothDamp(currentMouseDelta, targetMouseDelta, ref currentMouseDeltaVelocity, mouseSmoothTime);
cameraPitch -= currentMouseDelta.y * ySensitivity;
cameraPitch = Mathf.Clamp(cameraPitch, -70.0f, 70.0f);
playerCamera.localEulerAngles = Vector3.right * cameraPitch;
transform.Rotate(Vector3.up * currentMouseDelta.x * xSensitivity);
}
void UpdateMovement()
{
Vector2 targetDir = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
targetDir.Normalize();
currentDir = Vector2.SmoothDamp(currentDir, targetDir, ref currentDirVelocity, moveSmoothTime);
if (controller.isGrounded)
velocityY = 0.0f;
velocityY += gravity * Time.deltaTime;
Vector3 velocity = (transform.forward * currentDir.y + transform.right * currentDir.x) * moveSpeed + Vector3.up * velocityY;
controller.Move(velocity * Time.deltaTime);
}
void OnCollisionStay()
{
isGrounded = true;
}
void UpdateJump()
{
if (Input.GetKeyDown(KeyCode.Space) && isGrounded)
{
rb.AddForce(jump * jumpForce, ForceMode.Impulse);
isGrounded = false;
Debug.Log("JUMP");
}
}
}
In my script I can't seem to get the UpdateJump function to work as intended. When I press space I get the console message but the rb.AddForce appears to do nothing. what is the reason that I can't get my player controller to jump and how can I go about fixing this and making sure it doesn't occur again further down the line.

Guidance needed to understand quaternion and movetowards of gameobject

Hello I am trying to move a game object in 3d space I have searched the internet and found there are 3 ways to do that using turntoface(euler angles) or quaternion or navmesh agents
My problem is the game object default rotation is changing in using quaternions or move towards.
Can anyone help me understand why it is happening like that.
I want the capsule in slanted position.
//below code is using quaternions
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Guard : MonoBehaviour
{
public float speed = 5;
public float waitTime = .3f;
public float turnSpeed = 90;
public Transform pathHolder;
public Transform target;
void Start()
{
Vector3[] waypoints = new Vector3[pathHolder.childCount];
for (int i = 0; i < waypoints.Length; i++)
{
waypoints = pathHolder.GetChild(i).position;
waypoints = new Vector3(waypoints.x, transform.position.y, waypoints.z);
}
StartCoroutine(FollowPath(waypoints));
}
IEnumerator FollowPath(Vector3[] waypoints)
{
transform.position = waypoints[0];
int targetWaypointIndex = 1;
Vector3 targetWaypoint = waypoints[targetWaypointIndex];
while (true)
{
Quaternion targetRotation = Quaternion.LookRotation(targetWaypoint - transform.position);
transform.rotation = Quaternion.RotateTowards(transform.rotation, targetRotation, turnSpeed * Time.deltaTime);
if (transform.rotation == targetRotation)
{
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint, speed * Time.deltaTime);
if (transform.position == targetWaypoint)
{
targetWaypointIndex = (targetWaypointIndex + 1) % waypoints.Length;
targetWaypoint = waypoints[targetWaypointIndex];
yield return new WaitForSeconds(waitTime);
}
}
yield return null;
}
IEnumerator TurnToFace(Vector3 lookTarget)
{
Vector3 dirToLookTarget = (lookTarget - transform.position).normalized;
float targetAngle = 90 - Mathf.Atan2(dirToLookTarget.y, dirToLookTarget.x) * Mathf.Rad2Deg;
while (Mathf.Abs(Mathf.DeltaAngle(transform.eulerAngles.y, targetAngle)) > 0.05f)
{
float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, targetAngle, turnSpeed * Time.deltaTime);
transform.eulerAngles = Vector3.up * angle;
yield return null;
}
}
void OnDrawGizmos()
{
Vector3 startPosition = pathHolder.GetChild(0).position;
Vector3 previousPosition = startPosition;
foreach (Transform waypoint in pathHolder)
{
Gizmos.DrawSphere(waypoint.position, .3f);
Gizmos.DrawLine(previousPosition, waypoint.position);
previousPosition = waypoint.position;
}
Gizmos.DrawLine(previousPosition, startPosition);
}
}
}
//below code is using turntoface (euler angles concept)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Guard : MonoBehaviour
{
public float speed = 5;
public float waitTime = .3f;
public float turnSpeed = 90;
public Transform pathHolder;
void Start()
{
Vector3[] waypoints = new Vector3[pathHolder.childCount];
for (int i = 0; i < waypoints.Length; i++)
{
waypoints = pathHolder.GetChild(i).position;
waypoints = new Vector3(waypoints.x, transform.position.y, waypoints.z);
}
StartCoroutine(FollowPath(waypoints));
}
IEnumerator FollowPath(Vector3[] waypoints)
{
transform.position = waypoints[0];
int targetWaypointIndex = 1;
Vector3 targetWaypoint = waypoints[targetWaypointIndex];
transform.LookAt(targetWaypoint);
while (true)
{
transform.position = Vector3.MoveTowards(transform.position, targetWaypoint, speed * Time.deltaTime);
if (transform.position == targetWaypoint)
{
targetWaypointIndex = (targetWaypointIndex + 1) % waypoints.Length;
targetWaypoint = waypoints[targetWaypointIndex];
yield return new WaitForSeconds(waitTime);
yield return StartCoroutine(TurnToFace(targetWaypoint));
}
yield return null;
}
}
IEnumerator TurnToFace(Vector3 lookTarget)
{
Vector3 dirToLookTarget = (lookTarget - transform.position).normalized;
float targetAngle = 90 - Mathf.Atan2(dirToLookTarget.z, dirToLookTarget.x) * Mathf.Rad2Deg;
while (Mathf.DeltaAngle(transform.eulerAngles.y, targetAngle) > 0.05f)
{
float angle = Mathf.MoveTowardsAngle(transform.eulerAngles.y, targetAngle, turnSpeed * Time.deltaTime);
transform.eulerAngles = Vector3.up * angle;
yield return null;
}
}
void OnDrawGizmos()
{
Vector3 startPosition = pathHolder.GetChild(0).position;
Vector3 previousPosition = startPosition;
foreach (Transform waypoint in pathHolder)
{
Gizmos.DrawSphere(waypoint.position, .3f);
Gizmos.DrawLine(previousPosition, waypoint.position);
previousPosition = waypoint.position;
}
Gizmos.DrawLine(previousPosition, startPosition);
}
}
This link has all videos and required output for reference

How to flip the object when the mouse is facing the other direction?

so what I want is when the mouse is on the left the object switches to the left and when the mouse is on the right the weapon faces the right. Got any ideas??
public class WeaponParent : MonoBehaviour
{
public float blahblah = 90;
void Update()
{
faceMouse();
}
void faceMouse()
{
Vector2 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
Quaternion rotation = Quaternion.AngleAxis(angle -blahblah, Vector3.forward);
transform.rotation = rotation;
}
Hey guys, I figured it out.
{
public float blahblah = 90;
public float offset = 3f;
private SpriteRenderer spriteRender;
public SpriteRenderer brat;
private void Start()
{
spriteRender = GetComponent<SpriteRenderer>();
}
void Update()
{
faceMouse();
}
void faceMouse()
{
// Vector2 dir = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
// float angle = Mathf.Atan2(dir.y, dir.x) * Mathf.Rad2Deg;
// Quaternion rotation = Quaternion.AngleAxis(angle -blahblah, Vector3.forward);
// transform.rotation = rotation;
Vector3 difference = Camera.main.ScreenToWorldPoint(Input.mousePosition) - transform.position;
float rot2 = Mathf.Atan2(difference.y, difference.x) * Mathf.Rad2Deg;
transform.rotation = Quaternion.Euler(0f, 0f, rot2);
if(rot2 < 69 && rot2 > -69)
{
Debug.Log("Facing right");
transform.localScale = new Vector3(1, 1, 1);
brat.flipX = false;
}
else
{
Debug.Log("Facing left");
transform.localScale = new Vector3(1, -1, 1);
brat.flipX = true;
}
}
}

Flipping sprite in unity with weird movement script

I want to flip my sprites depending on which direction they are going and then stay in that position until they move again. I've tried velocity detection and the flipping the sprites accordingly, but since my movement is not by force but by changing position it can't detect velocity (I think), so any suggestions would be helpful.
Here's the movement script I've got so far:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Movement : MonoBehaviour
{
//DRAG AND DROP
bool isBeingDragged = false;
//POSITIONS AND TARGET
public float speed = 0.5f;
float timer = 0f;
public float waitTime;
public float distanceToAchieve = 0.2f;
bool isFollowing = true;
bool isWaiting = false;
//GOAL TARGET
public GameObject goalGameObject;
Vector2 target;
public Vector2 bounds = new Vector2(1.75f, 3);
private Vector2 RP;
private float startPosX;
private float startPosY;
void Start()
{
if (this.gameObject.tag == "1")
{
transform.position = RandomizePosition();
}
target = RandomizePosition();
isFollowing = true;
}
private void Update()
{
if (!isBeingDragged)
{
if (!isWaiting && Vector2.Distance(transform.position, target) < distanceToAchieve)
{
isWaiting = true;
isFollowing = false;
RandomizeGoal();
}
if (isWaiting)
{
timer += Time.deltaTime;
if (timer > waitTime)
{
timer = 0f;
isWaiting = false;
isFollowing = true;
}
}
}
}
private void FixedUpdate()
{
if (isFollowing && !isBeingDragged)
{
transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
if (isBeingDragged)
{
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
this.gameObject.transform.localPosition = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
}
}
Vector2 RandomizePosition()
{
RP = new Vector2(transform.position.x - Random.Range(-1f, 1f), transform.position.y - Random.Range(-1f, 1f));
if (RP.x < bounds.x && RP.x > bounds.x * -1 && RP.y < bounds.y && RP.y > bounds.y * -1)
{
return RP;
}
else
{
return new Vector2(transform.position.x, transform.position.y);
}
}
void RandomizeGoal()
{
waitTime = Random.Range(2, 10);
target = RandomizePosition();
goalGameObject.transform.position = target;
}
private void OnMouseDown()
{
isBeingDragged = true;
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
startPosX = mousePos.x - this.transform.localPosition.x;
startPosY = mousePos.y - this.transform.localPosition.y;
}
private void OnMouseUp()
{
isBeingDragged = false;
GetComponent<Merging>().CheckNearest();
}
}
private void FixedUpdate()
{
if (isFollowing && !isBeingDragged)
{
transform.position = Vector2.MoveTowards(transform.position, target, speed * Time.deltaTime);
}
if (isBeingDragged)
{
Vector3 mousePos;
mousePos = Input.mousePosition;
mousePos = Camera.main.ScreenToWorldPoint(mousePos);
// capture the current position of target
// by the way, why you use "loclPosition" for moving ??
// I don't thinkg this is appropriate.
var currentPos = this.gameObject.transform.localPosition;
var newPos = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
// then compare this with new position
bool isLeftSided = false;
if (newPos.x > currentPos.x)
{
isLeftSided = true;
}
else
{
isLeftSided = false;
}
// And figure out the direction . in this example, I wrote just right-left case
// use the y pos for up and down
// then flip the sprite ( this case, default is right sided )
this.gameObject.GetComponent<SpriteRenderer>().flipX. = isLeftSided;
this.gameObject.transform.localPosition = new Vector3(mousePos.x - startPosX, mousePos.y - startPosY, 0);
}
}

Arrow GameObject in Unity3d won't fly

I have implemented a bow and arrow script in unity5. But the arrow doesn't fly off. Can someone suggest why this happens. I'm a beginner.
This is the Bow Script.
using UnityEngine;
using System.Collections;
public class Bow : MonoBehaviour {
private GameObject arrow = null;
private Vector3 fwd = Vector3.zero;
public GameObject arrowPrefab = null;
public int initialSpeed = 30;
public GameObject launchPosition = null;
public float waitTime = 0.1f;
public LayerMask layerMask;
// Use this for initialization
void Start ()
{
}
void FixedUpdate()
{
fwd = transform.TransformDirection(Vector3.forward);
if (!Physics.Raycast(transform.position, fwd, 1, layerMask))
{
if (Input.GetMouseButtonDown(0))
{
Fire();
}
}
}
private void Fire()
{
//yield return new WaitForSeconds(waitTime);
new WaitForSeconds(waitTime);
arrow = (GameObject)Instantiate(arrowPrefab, launchPosition.transform.position, launchPosition.transform.rotation);
}
}
This is the Arrow Script
using UnityEngine;
using System.Collections;
public class Arrow : MonoBehaviour {
private Vector3 velocity = Vector3.zero;
private Vector3 newPos;
private Vector3 oldPos;
private bool hasHit = false;
private Vector3 direction;
private RaycastHit hit;
private GameObject follow;
private Vector3 dir;
private float dist;
public LayerMask layerMask;
public float speed;
public Transform arrowRotation;
public float forceToApply;
public float arrowGravity;
void Start()
{
newPos = transform.position;
oldPos = newPos;
velocity = speed * transform.forward;
}
void update()
{
if (hasHit)
{
transform.position = follow.transform.position;
transform.rotation = follow.transform.rotation;
return;
}
newPos += (velocity + direction) * Time.deltaTime;
dir = newPos - oldPos;
dist = dir.magnitude;
dir /= dist;
if(dist > 0)
{
if (Physics.Raycast(oldPos,dir,out hit,dist,layerMask))
{
newPos = hit.point;
if (hit.collider)
{
if (hit.rigidbody)
{
GameObject hitpoint = (GameObject)Instantiate(new GameObject(), hit.point, transform.root.rotation);
hitpoint.transform.parent = hit.transform;
follow = hitpoint;
GetComponent<Collider>().isTrigger = true;
hit.rigidbody.AddForceAtPosition(forceToApply * dir, hit.point);
hasHit = true;
}
else
{
enabled = false;
}
}
}
}
oldPos = transform.position;
transform.position = newPos;
velocity.y -= arrowGravity * Time.deltaTime;
arrowRotation.transform.rotation = Quaternion.LookRotation(dir);
}
}
You declare, but do not define 'direction' in your Arrow script. I suspect including it in the newPos calculation means nothing gets added.