c# does not contain a definition for and no extension method - c#

my code:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Controller2D))]
public class Player : MonoBehaviour
{
public float jumpHeight = 4;
public float timeToJumpApex = .4f;
float accelerationTimeAirborne = .2f;
float accelerationTimeGrounded = .1f;
float moveSpeed = 6;
float gravity;
float jumpVelocity;
Vector3 velocity;
float velocityXSmoothing;
Controller2D controller;
void Start()
{
controller = GetComponent<Controller2D>();
gravity = -(2 * jumpHeight) / Mathf.Pow(timeToJumpApex, 2);
jumpVelocity = Mathf.Abs(gravity) * timeToJumpApex;
print("Gravity: " + gravity + " Jump Velocity: " + jumpVelocity);
}
void Update()
{
if (controller.collisions.above || controller.collisions.below)
{
velocity.y = 0;
}
Vector2 input = new Vector2(Input.GetAxisRaw("Horizontal"), Input.GetAxisRaw("Vertical"));
if (Input.GetKeyDown(KeyCode.Space) && controller.collisions.below)
{
velocity.y = jumpVelocity;
}
float targetVelocityX = input.x * moveSpeed;
velocity.x = Mathf.SmoothDamp(velocity.x, targetVelocityX, ref velocityXSmoothing, (controller.collisions.below) ? accelerationTimeGrounded : accelerationTimeAirborne);
velocity.y += gravity * Time.deltaTime;
controller.Move(velocity * Time.deltaTime);
}
}
Controller2D code:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(BoxCollider2D))]
public class Controller2D : MonoBehaviour
{
public LayerMask collisionMask;
const float skinWidth = .015f;
public int horizontalRayCount = 4;
public int verticalRayCount = 4;
float horizontalRaySpacing;
float verticalRaySpacing;
new BoxCollider2D collider;
RaycastOrigins raycastOrigins;
internal object collisions;
void Start()
{
collider = GetComponent<BoxCollider2D>();
CalculateRaySpacing();
}
public void Move(Vector3 velocity)
{
UpdateRaycastOrigins();
if (velocity.x != 0)
{
HorizontalCollisions(ref velocity);
}
if (velocity.y != 0)
{
VerticalCollisions(ref velocity);
}
transform.Translate(velocity);
}
void HorizontalCollisions(ref Vector3 velocity)
{
float directionX = Mathf.Sign(velocity.x);
float rayLength = Mathf.Abs(velocity.x) + skinWidth;
for (int i = 0; i < horizontalRayCount; i++)
{
Vector2 rayOrigin = (directionX == -1) ? raycastOrigins.bottomLeft : raycastOrigins.bottomRight;
rayOrigin += Vector2.up * (horizontalRaySpacing * i);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.right * directionX, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.right * directionX * rayLength, Color.red);
if (hit)
{
velocity.x = (hit.distance - skinWidth) * directionX;
rayLength = hit.distance;
}
}
}
void VerticalCollisions(ref Vector3 velocity)
{
float directionY = Mathf.Sign(velocity.y);
float rayLength = Mathf.Abs(velocity.y) + skinWidth;
for (int i = 0; i < verticalRayCount; i++)
{
Vector2 rayOrigin = (directionY == -1) ? raycastOrigins.bottomLeft : raycastOrigins.topLeft;
rayOrigin += Vector2.right * (verticalRaySpacing * i + velocity.x);
RaycastHit2D hit = Physics2D.Raycast(rayOrigin, Vector2.up * directionY, rayLength, collisionMask);
Debug.DrawRay(rayOrigin, Vector2.up * directionY * rayLength, Color.red);
if (hit)
{
velocity.y = (hit.distance - skinWidth) * directionY;
rayLength = hit.distance;
}
}
}
void UpdateRaycastOrigins()
{
Bounds bounds = collider.bounds;
bounds.Expand(skinWidth * -2);
raycastOrigins.bottomLeft = new Vector2(bounds.min.x, bounds.min.y);
raycastOrigins.bottomRight = new Vector2(bounds.max.x, bounds.min.y);
raycastOrigins.topLeft = new Vector2(bounds.min.x, bounds.max.y);
raycastOrigins.topRight = new Vector2(bounds.max.x, bounds.max.y);
}
void CalculateRaySpacing()
{
Bounds bounds = collider.bounds;
bounds.Expand(skinWidth * -2);
horizontalRayCount = Mathf.Clamp(horizontalRayCount, 2, int.MaxValue);
verticalRayCount = Mathf.Clamp(verticalRayCount, 2, int.MaxValue);
horizontalRaySpacing = bounds.size.y / (horizontalRayCount - 1);
verticalRaySpacing = bounds.size.x / (verticalRayCount - 1);
}
struct RaycastOrigins
{
public Vector2 topLeft, topRight;
public Vector2 bottomLeft, bottomRight;
}
}
When I hover over "above" and "below" it give me the error
c# does not contain a definition for and no extension method,
can anyone see what I have done wrong?

internal object collisions;
Here you define collisions as object. Which means it does not have above nor below boolean properties.
Perhaps you need to define a new struct or class called collisions and define internal or public boolean properties above and below.

Related

In Unity 3D my character's left foot does not react properly when walking, it looks wobbly when I walk around,any ideas?

The main character from the Unity 3D tutorials that I followed, I believe not from the site, are producing a wobbly left foot. I did not put a foot IK because the issue is not placement. It seems like an origin point thing, but not sure so I turned here for help.
I tried to have the full range of motion of the Mecanim character but was unable to produce foot bones on the rig that seem to work even though I just imported the model and code.
Third Person Character code :
using System;
using System.Collections;
using UnityEngine;
namespace UnityStandardAssets.Characters.ThirdPerson
[RequireComponent(typeof(Rigidbody))]
[RequireComponent(typeof(CapsuleCollider))]
[RequireComponent(typeof(Animator))]
public class ThirdPersonCharacter : MonoBehaviour
{
[SerializeField] float m_MovingTurnSpeed = 360;
[SerializeField] float m_StationaryTurnSpeed = 180;
[SerializeField] float m_JumpPower = 12f;
[Range(1f, 4f)][SerializeField] float m_GravityMultiplier = 2f;
[SerializeField] float m_RunCycleLegOffset = 0.2f;
[SerializeField] float m_MoveSpeedMultiplier = 1f;
[SerializeField] float m_AnimSpeedMultiplier = 1f;
[SerializeField] float m_GroundCheckDistance = 0.1f;
Rigidbody m_Rigidbody;
Animator m_Animator;
bool m_IsGrounded;
float m_OrigGroundCheckDistance;
const float k_Half = 0.5f;
float m_TurnAmount;
float m_ForwardAmount;
Vector3 m_GroundNormal;
float m_CapsuleHeight;
Vector3 m_CapsuleCenter;
CapsuleCollider m_Capsule;
bool m_Crouching;
void Start()
{
m_Animator = GetComponent<Animator>();
m_Rigidbody = GetComponent<Rigidbody>();
m_Capsule = GetComponent<CapsuleCollider>();
m_CapsuleHeight = m_Capsule.height;
m_CapsuleCenter = m_Capsule.center;
m_Rigidbody.constraints = RigidbodyConstraints.FreezeRotationX | RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezeRotationZ;
m_OrigGroundCheckDistance = m_GroundCheckDistance;
}
public void Move(Vector3 move, bool crouch, bool jump)
{
if (move.magnitude > 1f) move.Normalize();
move = transform.InverseTransformDirection(move);
CheckGroundStatus();
move = Vector3.ProjectOnPlane(move, m_GroundNormal);
m_TurnAmount = Mathf.Atan2(move.x, move.z);
m_ForwardAmount = move.z;
ApplyExtraTurnRotation();
if (m_IsGrounded)
{
HandleGroundedMovement(crouch, jump);
}
else
{
HandleAirborneMovement();
}
ScaleCapsuleForCrouching(crouch);
PreventStandingInLowHeadroom();
UpdateAnimator(move);
}
void ScaleCapsuleForCrouching(bool crouch)
{
if (m_IsGrounded && crouch)
{
if (m_Crouching) return;
m_Capsule.height = m_Capsule.height / 2f;
m_Capsule.center = m_Capsule.center / 2f;
m_Crouching = true;
}
else
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
return;
}
m_Capsule.height = m_CapsuleHeight;
m_Capsule.center = m_CapsuleCenter;
m_Crouching = false;
}
}
void PreventStandingInLowHeadroom()
{
if (!m_Crouching)
{
Ray crouchRay = new Ray(m_Rigidbody.position + Vector3.up * m_Capsule.radius * k_Half, Vector3.up);
float crouchRayLength = m_CapsuleHeight - m_Capsule.radius * k_Half;
if (Physics.SphereCast(crouchRay, m_Capsule.radius * k_Half, crouchRayLength, Physics.AllLayers, QueryTriggerInteraction.Ignore))
{
m_Crouching = true;
}
}
}
void UpdateAnimator(Vector3 move)
{
m_Animator.SetFloat("Forward", m_ForwardAmount, 0.1f, Time.deltaTime);
m_Animator.SetFloat("Turn", m_TurnAmount, 0.1f, Time.deltaTime);
m_Animator.SetBool("Crouch", m_Crouching);
m_Animator.SetBool("OnGround", m_IsGrounded);
if (!m_IsGrounded)
{
m_Animator.SetFloat("Jump", m_Rigidbody.velocity.y);
}
float runCycle =
Mathf.Repeat(
m_Animator.GetCurrentAnimatorStateInfo(0).normalizedTime + m_RunCycleLegOffset, 1);
float jumpLeg = (runCycle < k_Half ? 1 : -1) * m_ForwardAmount;
if (m_IsGrounded)
{
m_Animator.SetFloat("JumpLeg", jumpLeg);
}
if (m_IsGrounded && move.magnitude > 0)
{
m_Animator.speed = m_AnimSpeedMultiplier;
}
else
{
m_Animator.speed = 1;
}
}
void HandleAirborneMovement()
{
Vector3 extraGravityForce = (Physics.gravity * m_GravityMultiplier) - Physics.gravity;
m_Rigidbody.AddForce(extraGravityForce);
m_GroundCheckDistance = m_Rigidbody.velocity.y < 0 ? m_OrigGroundCheckDistance : 0.01f;
}
void HandleGroundedMovement(bool crouch, bool jump)
{
if (jump && !crouch && m_Animator.GetCurrentAnimatorStateInfo(0).IsName("Grounded"))
{
m_Rigidbody.velocity = new Vector3(m_Rigidbody.velocity.x, m_JumpPower, m_Rigidbody.velocity.z);
m_IsGrounded = false;
m_Animator.applyRootMotion = false;
m_GroundCheckDistance = 0.1f;
}
}
void ApplyExtraTurnRotation()
{
float turnSpeed = Mathf.Lerp(m_StationaryTurnSpeed, m_MovingTurnSpeed, m_ForwardAmount);
transform.Rotate(0, m_TurnAmount * turnSpeed * Time.deltaTime, 0);
}
public void OnAnimatorMove()
{
if (m_IsGrounded && Time.deltaTime > 0)
{
Vector3 v = (m_Animator.deltaPosition * m_MoveSpeedMultiplier) / Time.deltaTime;
v.y = m_Rigidbody.velocity.y;
m_Rigidbody.velocity = v;
}
}
void CheckGroundStatus()
{
RaycastHit hitInfo;
Debug.DrawLine(transform.position + (Vector3.up * 0.1f), transform.position + (Vector3.up * 0.1f) + (Vector3.down * m_GroundCheckDistance));
if (Physics.Raycast(transform.position + (Vector3.up * 0.1f), Vector3.down, out hitInfo, m_GroundCheckDistance))
{
m_GroundNormal = hitInfo.normal;
m_IsGrounded = true;
m_Animator.applyRootMotion = true;
}
else
{
m_IsGrounded = false;
m_GroundNormal = Vector3.up;
m_Animator.applyRootMotion = false;
}
}
}

How to create a zoomable canvas image in Unity for mobile without scaling the main camera?

I have GameObject with Scroll Rect and Rect Mask in my canvas and there is an image in it. I want to zoom in and zoom out of that image. However I don't want to scale Main Camera because there will be other objects in the screen that I don't want to zoom. I searched it but all the tutorials are doing that by scaling Main Camera.
This video is exactly what I want but it doesn't work in android. https://www.youtube.com/watch?v=BFX3FpUnoio&ab_channel=JasonWeimann
This is the script in that video which is added to "image". I tried to modify it but I messed it up. How can I make it work in mobile?
using UnityEngine;
using UnityEngine.EventSystems;
public class UIZoomImage : MonoBehaviour, IScrollHandler
{
private Vector3 initialScale;
[SerializeField]
private float zoomSpeed = 0.1f;
[SerializeField]
private float maxZoom = 10f;
private void Awake()
{
initialScale = transform.localScale;
}
public void OnScroll(PointerEventData eventData)
{
var delta = Vector3.one * (eventData.scrollDelta.y * zoomSpeed);
var desiredScale = transform.localScale + delta;
desiredScale = ClampDesiredScale(desiredScale);
transform.localScale = desiredScale;
}
private Vector3 ClampDesiredScale(Vector3 desiredScale)
{
desiredScale = Vector3.Max(initialScale, desiredScale);
desiredScale = Vector3.Min(initialScale * maxZoom, desiredScale);
return desiredScale;
}
}
-------UPDATE---------
I found this in Unity forum: https://answers.unity.com/questions/1280592/pinch-and-zoom-functionality-on-canvas-ui-images.html
It almost works but I need to pinch the screen 2-3 to zoom in or zoom out. On first touch nothing happens. It's so annoying. I tried to change _minZoom, _maxZoom, speed and sensitivity values but didn't work.
This is the script there:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PinchableScrollRect : ScrollRect
{
[SerializeField] float _minZoom = .1f;
[SerializeField] float _maxZoom = 10;
[SerializeField] float _zoomLerpSpeed = 10f;
float _currentZoom = 1;
bool _isPinching = false;
float _startPinchDist;
float _startPinchZoom;
Vector2 _startPinchCenterPosition;
Vector2 _startPinchScreenPosition;
float _mouseWheelSensitivity = 1;
bool blockPan = false;
protected override void Awake()
{
Input.multiTouchEnabled = true;
}
private void Update()
{
if (Input.touchCount == 2)
{
if (!_isPinching)
{
_isPinching = true;
OnPinchStart();
}
OnPinch();
}
else
{
_isPinching = false;
if (Input.touchCount == 0)
{
blockPan = false;
}
}
//pc input
float scrollWheelInput = Input.GetAxis("Mouse ScrollWheel");
if (Mathf.Abs(scrollWheelInput) > float.Epsilon)
{
_currentZoom *= 1 + scrollWheelInput * _mouseWheelSensitivity;
_currentZoom = Mathf.Clamp(_currentZoom, _minZoom, _maxZoom);
_startPinchScreenPosition = (Vector2)Input.mousePosition;
RectTransformUtility.ScreenPointToLocalPointInRectangle(content, _startPinchScreenPosition, null, out _startPinchCenterPosition);
Vector2 pivotPosition = new Vector3(content.pivot.x * content.rect.size.x, content.pivot.y * content.rect.size.y);
Vector2 posFromBottomLeft = pivotPosition + _startPinchCenterPosition;
SetPivot(content, new Vector2(posFromBottomLeft.x / content.rect.width, posFromBottomLeft.y / content.rect.height));
}
//pc input end
if (Mathf.Abs(content.localScale.x - _currentZoom) > 0.001f)
content.localScale = Vector3.Lerp(content.localScale, Vector3.one * _currentZoom, _zoomLerpSpeed * Time.deltaTime);
}
protected override void SetContentAnchoredPosition(Vector2 position)
{
if (_isPinching || blockPan) return;
base.SetContentAnchoredPosition(position);
}
void OnPinchStart()
{
Vector2 pos1 = Input.touches[0].position;
Vector2 pos2 = Input.touches[1].position;
_startPinchDist = Distance(pos1, pos2) * content.localScale.x;
_startPinchZoom = _currentZoom;
_startPinchScreenPosition = (pos1 + pos2) / 2;
RectTransformUtility.ScreenPointToLocalPointInRectangle(content, _startPinchScreenPosition, null, out _startPinchCenterPosition);
Vector2 pivotPosition = new Vector3(content.pivot.x * content.rect.size.x, content.pivot.y * content.rect.size.y);
Vector2 posFromBottomLeft = pivotPosition + _startPinchCenterPosition;
SetPivot(content, new Vector2(posFromBottomLeft.x / content.rect.width, posFromBottomLeft.y / content.rect.height));
blockPan = true;
}
void OnPinch()
{
float currentPinchDist = Distance(Input.touches[0].position, Input.touches[1].position) * content.localScale.x;
_currentZoom = (currentPinchDist / _startPinchDist) * _startPinchZoom;
_currentZoom = Mathf.Clamp(_currentZoom, _minZoom, _maxZoom);
}
float Distance(Vector2 pos1, Vector2 pos2)
{
RectTransformUtility.ScreenPointToLocalPointInRectangle(content, pos1, null, out pos1);
RectTransformUtility.ScreenPointToLocalPointInRectangle(content, pos2, null, out pos2);
return Vector2.Distance(pos1, pos2);
}
static void SetPivot(RectTransform rectTransform, Vector2 pivot)
{
if (rectTransform == null) return;
Vector2 size = rectTransform.rect.size;
Vector2 deltaPivot = rectTransform.pivot - pivot;
Vector3 deltaPosition = new Vector3(deltaPivot.x * size.x, deltaPivot.y * size.y) * rectTransform.localScale.x;
rectTransform.pivot = pivot;
rectTransform.localPosition -= deltaPosition;
}
}
This script does the trick if the camera projection is set to ortho. From this
source.
using UnityEngine;
public class Zoom : MonoBehaviour {
public float zoomSpeed = 1;
public float targetOrtho;
public float smoothSpeed = 2.0f;
public float minOrtho = 1.0f;
public float maxOrtho = 20.0f;
void Start() {
targetOrtho = Camera.main.orthographicSize;
}
void Update () {
float scroll = Input.GetAxis ("Mouse ScrollWheel");
if (scroll != 0.0f) {
targetOrtho -= scroll * zoomSpeed;
targetOrtho = Mathf.Clamp (targetOrtho, minOrtho, maxOrtho);
}
Camera.main.orthographicSize = Mathf.MoveTowards (Camera.main.orthographicSize, targetOrtho, smoothSpeed * Time.deltaTime);
}
}
Why don't you scale the Image?!

How can i check when the object MoveTowards has reached to the new position and then rotate it?

private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
//squadMembers[i].transform.rotation = qua[i];
}
}
And calling it in the Update:
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
ChangeFormation();
}
if (move == true)
MoveToNewFormation();
}
Once when one of the squadMembers reached to the newpos then i want to make
squadMembers[i].transform.rotation = qua[i];
qua is a List and i want to rotate the squad member once he reached the newpos.
Inside MoveToNewFormation i thought to add after the loop the line:
if (squadMembers[i].transform.position == newpos[i])
{
squadMembers[i].transform.rotation = qua[i];
}
But it's after the loop so 'i' not exist.
This is the complete script:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SquadFormation : MonoBehaviour
{
enum Formation
{
Square, Circle, Triangle
}
public Transform squadMemeber;
public int columns = 4;
public int squareSpace = 10;
public int circleSpace = 40;
public int numberOfObjects = 20;
public float yOffset = 0;
public float speed = 3;
private Formation formation;
private GameObject[] squadMembers;
private List<Quaternion> qua = new List<Quaternion>();
private List<Vector3> newpos = new List<Vector3>();
private bool move = false;
// Use this for initialization
void Start()
{
formation = Formation.Square;
ChangeFormation();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.F))
{
ChangeFormation();
}
if (move == true)
MoveToNewFormation();
}
private void ChangeFormation()
{
switch (formation)
{
case Formation.Square:
FormationSquare();
break;
case Formation.Circle:
FormationCircle();
break;
}
}
private Vector3 FormationSquarePositionCalculation(int index) // call this func for all your objects
{
float posX = (index % columns) * squareSpace;
float posY = (index / columns) * squareSpace;
return new Vector3(posX, posY);
}
private void FormationSquare()
{
for (int i = 0; i < numberOfObjects; i++)
{
Transform go = Instantiate(squadMemeber);
Vector3 pos = FormationSquarePositionCalculation(i);
go.position = new Vector3(transform.position.x + pos.x, 0, transform.position.y + pos.y);
go.Rotate(new Vector3(0, -90, 0));
go.tag = "Squad Member";
}
formation = Formation.Circle;
}
private Vector3 FormationCirclePositionCalculation(Vector3 center, float radius, int index, float angleIncrement)
{
float ang = index * angleIncrement;
Vector3 pos;
pos.x = center.x + radius * Mathf.Sin(ang * Mathf.Deg2Rad);
pos.z = center.z + radius * Mathf.Cos(ang * Mathf.Deg2Rad);
pos.y = center.y;
return pos;
}
private void FormationCircle()
{
Vector3 center = transform.position;
float radius = (float)circleSpace / 2;
float angleIncrement = 360 / (float)numberOfObjects;
for (int i = 0; i < numberOfObjects; i++)
{
Vector3 pos = FormationCirclePositionCalculation(center, radius, i, angleIncrement);
var rot = Quaternion.LookRotation(center - pos);
pos.y = Terrain.activeTerrain.SampleHeight(pos);
pos.y = pos.y + yOffset;
newpos.Add(pos);
qua.Add(rot);
}
move = true;
formation = Formation.Square;
}
private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position = Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
//squadMembers[i].transform.rotation = qua[i];
}
//if (squadMembers[i].transform.position == newpos[i])
}
}
You can use a threshold and check the distance using that threshold.
Define threshold like this at start of script.
public float threshold = 0.1f;
Then change the MoveToNewFormation() function like this:
private void MoveToNewFormation()
{
squadMembers = GameObject.FindGameObjectsWithTag("Squad Member");
float step = speed * Time.deltaTime;
for (int i = 0; i < squadMembers.Length; i++)
{
squadMembers[i].transform.LookAt(newpos[i]);
squadMembers[i].transform.position =
Vector3.MoveTowards(squadMembers[i].transform.position, newpos[i], step);
if(Vector3.Distance(squadMembers[i].transform.position,newpos[i])<threshold){
squadMembers[i].transform.rotation = qua[i];
}
}
//if (squadMembers[i].transform.position == newpos[i])
}

Why when pressing the Z key the ship is moving fast up and not forward?

I can use W S A D or arrow keys to turn the ship. But when i press on Z the ship fast moving up. When i press on X it will stop the ship on place.
I can't figure out how to make the ship move forward.
But nothing make the ship move forward.
I used a break point and i see in Start in the SpacecraftControl script on the line:
Debug.Log("Transform forward is : " + transform.forward);
Whem i put the mouse cursor on the forward of transform i see: 0.0,1.0,0.0
And inside the forward i see: x = 0 y = 0 and z = -1.192093E-07
Here is a small short video clip i recorded now showing what happen when running the game and then pressing on Z.
Please watch all the video the the Z pressing is start from second 14.
Video Clip
In my ship inspector i have: Transform, Local Rotation, Mesh Filter, Mesh Renderer, Animator, RigidBody > Gravity unchecked, Mesh Collider > Convex is checked and the scripts: Spacecraft Control and UserInput.
Then in the menu i went to: Edit > Project Settings > Input
In Input i addeed a new place one size to 19. And called the new Axes: Throttle
And the scripts first the SpacecraftControl:
using UnityEngine;
using System.Collections;
[RequireComponent(typeof(Rigidbody))]
public class SpacecraftControl : MonoBehaviour
{
public float MaxEnginePower = 40f;
public float RollEffect = 50f;
public float PitchEffect = 50f;
public float YawEffect = 0.2f;
public float BankedTurnEffect = 0.5f;
public float AutoTurnPitch = 0.5f;
public float AutoRollLevel = 0.1f;
public float AutoPitchLevel = 0.1f;
public float AirBreaksEffect = 3f;
public float ThrottleChangeSpeed = 0.3f;
public float DragIncreaseFactor = 0.001f;
private float Throttle;
private bool AirBrakes;
private float ForwardSpeed;
private float EnginePower;
private float cur_MaxEnginePower;
private float RollAngle;
private float PitchAngle;
private float RollInput;
private float PitchInput;
private float YawInput;
private float ThrottleInput;
private float OriginalDrag;
private float OriginalAngularDrag;
private float AeroFactor = 1;
private bool Immobolized = false;
private float BankedTurnAmount;
private Rigidbody _rigidbody;
Collider[] cols;
void Start()
{
_rigidbody = GetComponent<Rigidbody> ();
OriginalDrag = _rigidbody.drag;
OriginalAngularDrag = _rigidbody.angularDrag;
for (int i = 0; i < transform.childCount; i++)
{
foreach (var componentsInChild in transform.GetChild(i).GetComponentsInChildren<WheelCollider>())
{
componentsInChild.motorTorque = 0.18f;
}
}
Debug.Log("Transform forward is : " + transform.forward);
}
public void Move(float rollInput, float pitchInput, float yawInput, float throttleInput, bool airBrakes)
{
this.RollInput = rollInput;
this.PitchInput = pitchInput;
this.YawInput = yawInput;
this.ThrottleInput = throttleInput;
this.AirBrakes = airBrakes;
ClampInput ();
CalculateRollandPitchAngles ();
AutoLevel ();
CalculateForwardSpeed ();
ControlThrottle ();
CalculateDrag ();
CalculateLinearForces ();
CalculateTorque ();
if (Throttle < 0.1f)
{
Vector3 currentVelocity = _rigidbody.velocity;
Vector3 newVelocity = currentVelocity * Time.deltaTime;
_rigidbody.velocity = currentVelocity - newVelocity;
}
}
void ClampInput()
{
RollInput = Mathf.Clamp (RollInput, -1, 1);
PitchInput = Mathf.Clamp (PitchInput, -1, 1);
YawInput = Mathf.Clamp (YawInput, -1, 1);
ThrottleInput = Mathf.Clamp (ThrottleInput, -1, 1);
}
void CalculateRollandPitchAngles()
{
Vector3 flatForward = transform.forward;
flatForward.y = 0;
if (flatForward.sqrMagnitude > 0)
{
flatForward.Normalize ();
Vector3 localFlatForward = transform.InverseTransformDirection (flatForward);
PitchAngle = Mathf.Atan2 (localFlatForward.y, localFlatForward.z);
Vector3 flatRight = Vector3.Cross (Vector3.up, flatForward);
Vector3 localFlatRight = transform.InverseTransformDirection (flatRight);
RollAngle = Mathf.Atan2 (localFlatRight.y, localFlatRight.x);
}
}
void AutoLevel()
{
BankedTurnAmount = Mathf.Sin (RollAngle);
if (RollInput == 0)
{
RollInput = -RollAngle * AutoRollLevel;
}
if (PitchInput == 0f)
{
PitchInput = -PitchAngle * AutoPitchLevel;
PitchInput -= Mathf.Abs (BankedTurnAmount * BankedTurnAmount * AutoTurnPitch);
}
}
void CalculateForwardSpeed()
{
Vector3 localVelocity = transform.InverseTransformDirection (_rigidbody.velocity);
ForwardSpeed = Mathf.Max (0, localVelocity.z);
}
void ControlThrottle()
{
if (Immobolized)
{
ThrottleInput = -0.5f;
}
Throttle = Mathf.Clamp01 (Throttle + ThrottleInput * Time.deltaTime * ThrottleChangeSpeed);
EnginePower = Throttle * MaxEnginePower;
}
void CalculateDrag()
{
float extraDrag = _rigidbody.velocity.magnitude * DragIncreaseFactor;
//_rigidbody.drag = (AirBrakes ? (OriginalDrag + ) * AirBreaksEffect : OriginalDrag * extraDrag);
_rigidbody.drag = AirBrakes ? (OriginalDrag * AirBreaksEffect) : OriginalDrag;
_rigidbody.drag *= extraDrag;
_rigidbody.angularDrag = OriginalAngularDrag * ForwardSpeed / 1000 + OriginalAngularDrag;
}
void CalculateLinearForces()
{
Vector3 forces = Vector3.zero;
forces += EnginePower * transform.forward;
_rigidbody.AddForce (forces);
}
void CalculateTorque()
{
Vector3 torque = Vector3.zero;
torque += PitchInput * PitchEffect * transform.right;
torque += YawInput * YawEffect * transform.up;
torque += -RollInput * RollEffect * transform.forward;
torque += BankedTurnAmount * BankedTurnEffect * transform.up;
_rigidbody.AddTorque (torque * AeroFactor);
}
public void Immobilize()
{
Immobolized = true;
}
public void Reset()
{
Immobolized = false;
}
}
And the UserInput script:
using UnityEngine;
using System.Collections;
public class UserInput : MonoBehaviour {
SpacecraftControl _spacecraftcontrol;
// Use this for initialization
void Start ()
{
_spacecraftcontrol = GetComponent<SpacecraftControl> ();
}
void FixedUpdate()
{
float roll = Input.GetAxis ("Horizontal");
float pitch = Input.GetAxis ("Vertical");
bool airBrakes = Input.GetButton ("Fire1");
float throttle = Input.GetAxis ("Throttle");
_spacecraftcontrol.Move (roll, pitch, 0, throttle, airBrakes);
}
}

Unity3D Mecanim Character stopping before turning

so for the past few days I've been working on a character controller in Unity3D using mecanim. It's not based off of my own code, but off of a tutorial I found online, of course that tutorial was meant for Unity 4, so I am running in to small problems here and there, but nothing I couldn't fix up until now.
So the basic problem is that my character seems to (without reason) stop all his momentum and slowly turns around when I try to make a hard 180 degrees turn, afterwards he continues to run like normal again, but I don't see why he would suddenly stop turning.
Here is my character logic script:
using UnityEngine;
using System.Collections;
public class characterLogic : MonoBehaviour {
[SerializeField]
private Animator animator;
[SerializeField]
private FollowCamera gamecam;
[SerializeField]
private float directionSpeed = 1.5f;
[SerializeField]
private float directionDampTime = 0.25f;
[SerializeField]
private float rotationDegreePerSecond = 120f;
[SerializeField]
private float speedDampTime = 0.05f;
private float speed = 0.0f;
private float direction = 0.0f;
private float charAngle = 0f;
private float horizontal = 0.0f;
private float vertical = 0.0f;
private AnimatorStateInfo stateInfo;
private AnimatorTransitionInfo transInfo;
private int m_LocomotionId = 0;
private int m_LocomotionPivotLId = 0;
private int m_LocomotionPivotRId = 0;
private int m_LocomotionPivotLTransId = 0;
private int m_LocomotionPivotRTransId = 0;
public Animator Animator
{
get
{
return this.animator;
}
}
public float Speed
{
get
{
return this.speed;
}
}
public float LocomotionThreshold { get { return 0.2f; } }
// Use this for initialization
void Start () {
animator = GetComponent<Animator>();
if(animator.layerCount >= 2)
{
animator.SetLayerWeight(1, 1);
}
m_LocomotionId = Animator.StringToHash("Base Layer.Locomotion");
m_LocomotionPivotLId = Animator.StringToHash("Base Layer.LocomotionPivotL");
m_LocomotionPivotRId = Animator.StringToHash("Base Layer.LocomotionPivotR");
m_LocomotionPivotLTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotL");
m_LocomotionPivotRTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotR");
}
public void keysToWorldSpace (Transform root, Transform camera, ref float directionOut, ref float speedOut, ref float angleOut, bool isPivoting){
Vector3 rootDirection = root.forward;
Vector3 keyDirection = new Vector3 (horizontal, 0, vertical);
speedOut = keyDirection.sqrMagnitude;
//get camera rotation
Vector3 cameraDirection = camera.forward;
cameraDirection.y = 0.0f;
Quaternion referentialShift = Quaternion.FromToRotation (Vector3.forward, cameraDirection);
//convert key input to world space coordinates
Vector3 moveDirection = referentialShift * keyDirection;
Vector3 axisSign = Vector3.Cross (moveDirection, rootDirection);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), moveDirection, Color.green);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), axisSign, Color.red);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), rootDirection, Color.magenta);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), keyDirection, Color.blue);
float angleRootToMove = Vector3.Angle(rootDirection, moveDirection) * (axisSign.y >= 0 ? -1f : 1f);
if (!isPivoting)
{
angleOut = angleRootToMove;
}
angleRootToMove /= 180f;
directionOut = angleRootToMove * directionSpeed;
}
// Update is called once per frame
void Update () {
if (animator) {
stateInfo = animator.GetCurrentAnimatorStateInfo(0);
transInfo = animator.GetAnimatorTransitionInfo(0);
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
charAngle = 0f;
direction = 0f;
keysToWorldSpace (this.transform, gamecam.transform, ref direction, ref speed, ref charAngle, isInPivot());
animator.SetFloat ("Speed", speed);
animator.SetFloat ("Direction", direction, directionDampTime, Time.deltaTime);
if(speed > LocomotionThreshold){
if(!isInPivot()){
Animator.SetFloat("Angle", charAngle);
}
}
if(speed < LocomotionThreshold && Mathf.Abs(horizontal) < 0.05f){
animator.SetFloat("Direction", 0f);
animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);
}
Debug.Log(Speed);
Debug.Log(charAngle);
}
}
void FixedUpdate() {
if (IsInLocomotion () && ((direction >= 0 && horizontal >= 0) || (direction < 0 && horizontal < 0))) {
Vector3 rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, rotationDegreePerSecond * (horizontal < 0f ? -1f : 1f), 0f), Mathf.Abs(horizontal));
Quaternion deltaRotation = Quaternion.Euler(rotationAmount * Time.deltaTime);
this.transform.rotation = (this.transform.rotation * deltaRotation);
}
}
public bool isInPivot(){
return stateInfo.fullPathHash == m_LocomotionPivotLId ||
stateInfo.fullPathHash == m_LocomotionPivotRId ||
transInfo.nameHash == m_LocomotionPivotLTransId ||
transInfo.nameHash == m_LocomotionPivotRTransId;
}
public bool IsInLocomotion(){
return stateInfo.fullPathHash == m_LocomotionId;
}
}
I believe it either has to do something with this script or with the transitions within mecanim. I also ported the finished product (found here: https://github.com/jm991/UnityThirdPersonTutorial ) of the tutorial over to Unity 5 and didn't experience the same problem there, I am not entirely sure what the difference is which gives me this problem, but if any of you know or find out, please let me know.
I found the problem myself already!
Here is the new code in case anyone is interested in the future:
using UnityEngine;
using System.Collections;
public class characterLogic : MonoBehaviour {
[SerializeField]
private Animator animator;
[SerializeField]
private FollowCamera gamecam;
[SerializeField]
private float directionSpeed = 1.5f;
[SerializeField]
private float directionDampTime = 0.25f;
[SerializeField]
private float rotationDegreePerSecond = 120f;
[SerializeField]
private float speedDampTime = 0.05f;
[SerializeField]
private float fovDampTime = 3f;
private float horizontal = 0.0f;
private float vertical = 0.0f;
private float speed = 0.0f;
private float direction = 0.0f;
private float charAngle = 0f;
private const float SPRINT_SPEED = 2.0f;
private const float SPRINT_FOV = 75.0f;
private const float NORMAL_FOV = 60.0f;
private const float WALK_SPEED = 0.1f;
private AnimatorStateInfo stateInfo;
private AnimatorTransitionInfo transInfo;
private int m_LocomotionId = 0;
private int m_LocomotionPivotLId = 0;
private int m_LocomotionPivotRId = 0;
private int m_LocomotionPivotLTransId = 0;
private int m_LocomotionPivotRTransId = 0;
public Animator Animator
{
get
{
return this.animator;
}
}
public float Speed
{
get
{
return this.speed;
}
}
public float LocomotionThreshold { get { return 0.2f; } }
// Use this for initialization
void Start () {
animator = GetComponent<Animator>();
if(animator.layerCount >= 2)
{
animator.SetLayerWeight(1, 1);
}
m_LocomotionId = Animator.StringToHash("Base Layer.Locomotion");
m_LocomotionPivotLId = Animator.StringToHash("Base Layer.LocomotionPivotL");
m_LocomotionPivotRId = Animator.StringToHash("Base Layer.LocomotionPivotR");
m_LocomotionPivotLTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotL");
m_LocomotionPivotRTransId = Animator.StringToHash("Base Layer.Locomotion -> Base Layer.LocomotionPivotR");
}
public void keysToWorldSpace (Transform root, Transform camera, ref float directionOut, ref float speedOut, ref float angleOut, bool isPivoting){
Vector3 rootDirection = root.forward;
Vector3 keyDirection = new Vector3 (horizontal, 0, vertical);
speedOut = keyDirection.sqrMagnitude;
//get camera rotation
Vector3 cameraDirection = camera.forward;
cameraDirection.y = 0.0f;
Quaternion referentialShift = Quaternion.FromToRotation(Vector3.forward, Vector3.Normalize(cameraDirection));
//convert key input to world space coordinates
Vector3 moveDirection = referentialShift * keyDirection;
Vector3 axisSign = Vector3.Cross (moveDirection, rootDirection);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), moveDirection, Color.green);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), axisSign, Color.red);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), rootDirection, Color.magenta);
Debug.DrawRay (new Vector3(root.position.x, root.position.y + 2f, root.position.z), keyDirection, Color.blue);
float angleRootToMove = Vector3.Angle(rootDirection, moveDirection) * (axisSign.y >= 0 ? -1f : 1f);
if (!isPivoting)
{
angleOut = angleRootToMove;
}
angleRootToMove /= 180f;
directionOut = angleRootToMove * directionSpeed;
}
// Update is called once per frame
void Update () {
if (animator) {
stateInfo = animator.GetCurrentAnimatorStateInfo(0);
transInfo = animator.GetAnimatorTransitionInfo(0);
horizontal = Input.GetAxis("Horizontal");
vertical = Input.GetAxis("Vertical");
charAngle = 0f;
direction = 0f;
float charSpeed = 0f;
keysToWorldSpace (this.transform, gamecam.transform, ref direction, ref charSpeed, ref charAngle, isInPivot());
if (Input.GetButton("Sprint"))
{
speed = Mathf.Lerp(speed, SPRINT_SPEED, Time.deltaTime);
gamecam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(gamecam.GetComponent<Camera>().fieldOfView, SPRINT_FOV, fovDampTime * Time.deltaTime);
}
else
{
speed = charSpeed;
gamecam.GetComponent<Camera>().fieldOfView = Mathf.Lerp(gamecam.GetComponent<Camera>().fieldOfView, NORMAL_FOV, fovDampTime * Time.deltaTime);
}
if (Input.GetButton("Walk"))
{
speed = Mathf.Lerp(speed, WALK_SPEED, Time.deltaTime);
}
else
{
speed = charSpeed;
}
animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);
animator.SetFloat("Direction", direction, directionDampTime, Time.deltaTime);
if(speed > LocomotionThreshold){
if(!isInPivot()){
Animator.SetFloat("Angle", charAngle);
}
}
if(speed < LocomotionThreshold && Mathf.Abs(horizontal) < 0.05f){
animator.SetFloat("Direction", 0f);
animator.SetFloat("Speed", speed, speedDampTime, Time.deltaTime);
}
Debug.Log(Speed);
Debug.Log(charAngle);
}
}
void FixedUpdate() {
if (IsInLocomotion () && ((direction >= 0 && horizontal >= 0) || (direction < 0 && horizontal < 0))) {
Vector3 rotationAmount = Vector3.Lerp(Vector3.zero, new Vector3(0f, rotationDegreePerSecond * (horizontal < 0f ? -1f : 1f), 0f), Mathf.Abs(horizontal));
Quaternion deltaRotation = Quaternion.Euler(rotationAmount * Time.deltaTime);
this.transform.rotation = (this.transform.rotation * deltaRotation);
}
}
public bool isInPivot(){
return stateInfo.fullPathHash == m_LocomotionPivotLId ||
stateInfo.fullPathHash == m_LocomotionPivotRId ||
transInfo.nameHash == m_LocomotionPivotLTransId ||
transInfo.nameHash == m_LocomotionPivotRTransId;
}
public bool IsInLocomotion(){
return stateInfo.fullPathHash == m_LocomotionId;
}
}
It turned out that the guy who made the original code was using a dampTime on his speed due to which he wouldn't instantly stand still if he'd let go off a button. It's something he hadn't explained in his tutorial yet, so I must have missed it. Anyways I hope this might help anyone in the future with a similar problem.

Categories

Resources