How to set an initial value for UI_Knob? - c#

I am trying to set an initial value for UI.Extensions UI_Knob
see link to UI.Extensions repo UI.Extensions bitbutcket
Through some searching I have found maybe the best way to set an initial value is to use simulated pointerEventData and pass it to the script using ExecuteEvents, since the UI_Knob script uses the mouse position to set it's value.
--BELOW IS THE CODE FOR THE UI_Knob--
/// Credit Tomasz Schelenz
/// Sourced from - https://bitbucket.org/ddreaper/unity-ui-
//ONLY ALLOW ROTATION WITH POINTER OVER THE CONTROL
public void OnPointerDown(PointerEventData eventData)
{
_canDrag = true;
}
public void OnPointerUp(PointerEventData eventData)
{
_canDrag = false;
}
public void OnPointerEnter(PointerEventData eventData)
{
_canDrag = true;
}
public void OnPointerExit(PointerEventData eventData)
{
_canDrag = true; // Now you can drag with pointer OFF control.
}
public void OnBeginDrag(PointerEventData eventData)
{
SetInitPointerData(eventData);
}
void SetInitPointerData(PointerEventData eventData)
{
_initRotation = transform.rotation;
_currentVector = eventData.position - (Vector2)transform.position;
_initAngle = Mathf.Atan2(_currentVector.y, _currentVector.x) * Mathf.Rad2Deg;
}
public void OnDrag(PointerEventData eventData)
{
//CHECK IF CAN DRAG
if (!_canDrag)
{
SetInitPointerData(eventData);
return;
}
_currentVector = eventData.position - (Vector2)transform.position;
_currentAngle = Mathf.Atan2(_currentVector.y, _currentVector.x) * Mathf.Rad2Deg;
Quaternion addRotation = Quaternion.AngleAxis(_currentAngle - _initAngle, this.transform.forward);
addRotation.eulerAngles = new Vector3(0, 0, addRotation.eulerAngles.z);
Quaternion finalRotation = _initRotation * addRotation;
if (direction == Direction.CW)
{
knobValue = 1 - (finalRotation.eulerAngles.z / 360f);
if (snapToPosition)
{
SnapToPosition(ref knobValue);
finalRotation.eulerAngles = new Vector3(0, 0, 360 - 360 * knobValue);
}
}
else
{
knobValue = (finalRotation.eulerAngles.z / 360f);
if (snapToPosition)
{
SnapToPosition(ref knobValue);
finalRotation.eulerAngles = new Vector3(0, 0, 360 * knobValue);
}
}
//PREVENT OVERROTATION
if (Mathf.Abs(knobValue - _previousValue) > 0.5f)
{
if (knobValue < 0.5f && loops > 1 && _currentLoops < loops - 1)
{
_currentLoops++;
}
else if (knobValue > 0.5f && _currentLoops >= 1)
{
_currentLoops--;
}
else
{
if (knobValue > 0.5f && _currentLoops == 0)
{
knobValue = 0;
transform.localEulerAngles = Vector3.zero;
SetInitPointerData(eventData);
InvokeEvents(knobValue + _currentLoops);
return;
}
else if (knobValue < 0.5f && _currentLoops == loops - 1)
{
knobValue = 1;
transform.localEulerAngles = Vector3.zero;
SetInitPointerData(eventData);
InvokeEvents(knobValue + _currentLoops);
return;
}
}
}
//CHECK MAX VALUE
if (maxValue > 0)
{
if (knobValue + _currentLoops > maxValue)
{
knobValue = maxValue;
float maxAngle = direction == Direction.CW ? 360f - 360f * maxValue : 360f * maxValue;
transform.localEulerAngles = new Vector3(0, 0, maxAngle);
SetInitPointerData(eventData);
InvokeEvents(knobValue);
return;
}
}
transform.rotation = finalRotation;
InvokeEvents(knobValue + _currentLoops);
_previousValue = knobValue;
}
private void SnapToPosition(ref float knobValue)
{
float snapStep = 1 / (float)snapStepsPerLoop;
float newValue = Mathf.Round(knobValue / snapStep) * snapStep;
knobValue = newValue;
}
private void InvokeEvents(float value)
{
if (clampOutput01)
value /= loops;
OnValueChanged.Invoke(value);
}
}
[System.Serializable]
public class KnobFloatValueEvent : UnityEvent<float> { }
}

I Answered my own question without using simulated mouse data. Instead, I added a Start() method with MyStartingAngle() method. See below. I chopped up the UI_Knob's method for rotation/setting value and basically just injected my own angle. I would still like to know how to perform this with simulated mouse data if anyone is willing. I would appreciate any input on my solution as well. Thanks for reading!!
// ADD THIS INTO UI_Knob script below initialization.
// I added this here to allow for setting an initial rotation/value.
void Start(){
float myFirstAngle = 180f;
MyStartingAngle (myFirstAngle);
}
void MyStartingAngle(float angle){
_initRotation = transform.rotation;
Quaternion addRotation = Quaternion.AngleAxis(angle, this.transform.forward);
addRotation.eulerAngles = new Vector3(0, 0, addRotation.eulerAngles.z);
Quaternion finalRotation = _initRotation * addRotation;
knobValue = 1 - (finalRotation.eulerAngles.z / 360f);
transform.rotation = finalRotation;
InvokeEvents(knobValue + _currentLoops);
_previousValue = knobValue;
}

Related

Trying endless runner game in unity 3d with 5Lane at place of 3Lane

Here is the code I m trying to edit however, the condition under the if else loops are not executing the task. In this code lanedistance is constant float variable with value 2.0f. As describe earlier it is 5lane endless runner so desired lane is considered as int variable with value 2 for middle (Ext. Left = 0, Left = 1, Middle = 2, Right = 3, Ext. Right = 4) -----------------
// Start is called before the first frame update
void Start()
{
controller = GetComponent<CharacterController>();
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.LeftArrow))
MoveLane(false);
if (Input.GetKeyDown(KeyCode.RightArrow))
MoveLane(true);
Vector3 targetposition = transform.position.z * Vector3.forward;
if (desiredLane == 0)
{
targetposition += Vector3.left * laneDistance;
}
else if (desiredLane == 1)
{
if(Input.GetKeyDown(KeyCode.LeftArrow))
{ //Debug.Log("1i condition");
MoveLane(true);
targetposition += Vector3.left * laneDistance;
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{
//Debug.Log("1e condition");
MoveLane(false);
targetposition += Vector3.right * laneDistance;
}
}
else if (desiredLane == 3)
{
if(Input.GetKeyDown(KeyCode.LeftArrow))
{
//Debug.Log("3i condition");
MoveLane(true);
targetposition += Vector3.left * laneDistance;
}
else if (Input.GetKeyDown(KeyCode.RightArrow))
{ //Debug.Log("3e condition");
MoveLane(true);
targetposition += Vector3.right * laneDistance;
}
}
else if (desiredLane == 4)// ----------------------
targetposition += Vector3.right * laneDistance;
Vector3 moveVector = Vector3.zero;
moveVector.x = (targetposition - transform.position).normalized.x * speed;
moveVector.y = -0.1f;
moveVector.z = speed;
controller.Move(moveVector * Time.deltaTime);
}
private void MoveLane(bool goingRight)
{
desiredLane += (goingRight) ? 5 : -1;// ------------------
desiredLane = Mathf.Clamp(desiredLane, 0, 4);// ------------------
Debug.Log("Value is: "+desiredLane);
}
}
I guess your code can be simplified a lot.
Also why would you handle the first two GetKeyDown statements always without any check at all? And what happened to the case where desiredLane == 2?
And why do you use
desiredLane += (goingRight) ? 5 : -1
it should probably rather be
desiredLane += (goingRight) ? 1 : -1
I'd say you rather want to do something like
// Configure these two vis the Inspector!
public float sidewardsSpeed;
public float forwardSpeed;
// Not necessary but this way you can give your checks handy names
private bool CanMoveLeft => desiredLane > 0;
private bool CanMoveRight => desiredLane < 4;
float targetPositionX;
void Start()
{
targetPositionX = transform.position.x;
}
void Update()
{
// This is for the sidewards movement
// It's enough to simply check the value of your index ONCE instead of
// covering each possible case ;)
if (CanMoveLeft && Input.GetKeyDown(KeyCode.LeftArrow))
MoveLane(false);
else if (CanMoveRight && Input.GetKeyDown(KeyCode.RightArrow))
MoveLane(true);
// Finally calculate a smoothed movement on the individual axes
var currentPosition = transform.position;
var deltaX = targetPositionX - currentPosition.x;
var x = Mathf.Min(deltaX, Mathf.Sign(deltaX) * sidewardsSpeed * Time.deltaTime);
var y = -0.1f * Time.deltaTime;
var z = forwardSpeed * Time.deltaTime;
// And then apply both movements
controller.Move(new Vector3(x, y, z));
}
private void MoveLane(bool goingRight)
{
var direction = goingRight ? 1 : -1;
desiredLane += direction;
desiredLane = Mathf.Clamp(desiredLane, 0, 4);
Debug.Log("Value is: "+desiredLane);
// Also directly calculate the target X position
targetPositionX = (desiredLane - 2) * laneDistance;
}

How can i move the player randomly between the waypoints?

What i'm trying to do is once the random flag is true move the player between the waypoints randomly.
but just calling the random method is not enough.
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
public class Waypoints : MonoBehaviour
{
public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 10f;
public float slowDownSpeed = 3f;
public float reverseSlowDownSpeed = 3f;
public float rotationSpeed = 1f;
private int targetsIndex = 0;
private Vector3 originalPosition;
private GameObject[] players;
public Transform reverseTarget;
private int reverseTargetsIndex = 0;
private Vector3 reverseOriginalPosition;
public bool random = false;
// Use this for initialization
void Start()
{
waypoints = GameObject.FindGameObjectsWithTag("Blocks");
players = GameObject.FindGameObjectsWithTag("Player");
originalPosition = players[0].transform.localPosition;
}
// Update is called once per frame
void Update()
{
if (random == true)
{
RandomWayPointsAI();
}
else
{
WayPointsAI();
}
}
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);
//move towards the player
if (distance < 30)
{
players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
}
else
{
players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
}
if (distance < target.transform.localScale.magnitude)
{
targetsIndex++;
}
}
private void ReverseWayPointsAI()
{
if (reverseTargetsIndex == 0)
reverseTargetsIndex = waypoints.Length - 1;
reverseTarget = waypoints[reverseTargetsIndex].transform;
float distance = Vector3.Distance(players[1].transform.position, reverseTarget.transform.position);
players[1].transform.rotation = Quaternion.Slerp(players[1].transform.rotation, Quaternion.LookRotation(reverseTarget.position - players[1].transform.position), rotationSpeed * Time.deltaTime);
//move towards the player
if (distance < 30)
{
players[1].transform.position += players[1].transform.forward * reverseSlowDownSpeed * Time.deltaTime;
}
else
{
players[1].transform.position += players[1].transform.forward * moveSpeed * Time.deltaTime;
}
if (distance < reverseTarget.transform.localScale.magnitude)
{
reverseTargetsIndex--;
}
}
void RandomWayPointsAI()
{
if (random == true)
{
int index = UnityEngine.Random.Range(0, waypoints.Length);
target = waypoints[index].transform;
}
}
void DrawLinesInScene()
{
// draw lines between each checkpoint //
for (int i = 0; i < waypoints.Length - 1; i++)
{
Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
}
// draw a line between the original transform start position
// and the current transform position //
Debug.DrawLine(originalPosition, players[0].transform.position, Color.red);
Debug.DrawLine(reverseOriginalPosition, players[1].transform.position, Color.red);
// draw a line between current transform position and the next waypoint target
// each time reached a waypoint.
if (target != null)
Debug.DrawLine(target.transform.position, players[0].transform.position, Color.green);
if (reverseTarget != null)
Debug.DrawLine(reverseTarget.transform.position, players[1].transform.position, Color.green);
}
void AddColliderToWaypoints()
{
foreach (GameObject go in waypoints)
{
SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
sc.isTrigger = true;
}
}
}
Inside the Update i'm checking if random is true then calling the RandomWayPointsAI(); but it's not moving the player it's just keep picking up each frame a new random waypoint but that's it.
void Update()
{
if (random == true)
{
RandomWayPointsAI();
}
else
{
WayPointsAI();
}
}
Here is your answer. First you are not writing the movement code in the random function and you are expecting it to move.
bool getNextRandom = true;
void RandomWayPointsAI()
{
if (random == true && getNextRandom)
{
int index = UnityEngine.Random.Range(0, waypoints.Length);
target = waypoints[index].transform;
getNextRandom = false;
}
float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);
//move towards the player
if (distance < 30)
{
players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
}
else
{
players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
}
if (distance < target.transform.localScale.magnitude)
{
getNextRandom = true;
}
}
Further you can imporve the solution by moving the movement code to another function which will give you better control
public GameObject[] waypoints;
public Transform target;
public float moveSpeed = 10f;
public float slowDownSpeed = 3f;
public float reverseSlowDownSpeed = 3f;
public float rotationSpeed = 1f;
private int targetsIndex = 0;
private Vector3 originalPosition;
private GameObject[] players;
public Transform reverseTarget;
private int reverseTargetsIndex = 0;
private Vector3 reverseOriginalPosition;
public bool random = false;
public bool getNextRandom = true;
// Use this for initialization
void Start()
{
waypoints = GameObject.FindGameObjectsWithTag("Blocks");
players = GameObject.FindGameObjectsWithTag("Player");
originalPosition = players[0].transform.localPosition;
}
// Update is called once per frame
void Update()
{
if (random == true)
{
RandomWayPointsAI();
}
else
{
WayPointsAI();
}
}
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
if (MovePlayer())
targetsIndex++;
}
private void ReverseWayPointsAI()
{
if (reverseTargetsIndex == 0)
reverseTargetsIndex = waypoints.Length - 1;
reverseTarget = waypoints[reverseTargetsIndex].transform;
if (MovePlayer())
reverseTargetsIndex--;
}
void RandomWayPointsAI()
{
if (random == true && getNextRandom)
{
int index = UnityEngine.Random.Range(0, waypoints.Length);
target = waypoints[index].transform;
getNextRandom = false;
}
getNextRandom = MovePlayer();
}
bool MovePlayer()
{
float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);
//move towards the player
if (distance < 30)
{
players[0].transform.localPosition += players[0].transform.forward * slowDownSpeed * Time.deltaTime;
}
else
{
players[0].transform.localPosition += players[0].transform.forward * moveSpeed * Time.deltaTime;
}
if (distance < target.transform.localScale.magnitude)
return true;
else
return false;
}
void DrawLinesInScene()
{
// draw lines between each checkpoint //
for (int i = 0; i < waypoints.Length - 1; i++)
{
Debug.DrawLine(waypoints[i].transform.position, waypoints[i + 1].transform.position, Color.blue);
}
// draw a line between the original transform start position
// and the current transform position //
Debug.DrawLine(originalPosition, players[0].transform.position, Color.red);
Debug.DrawLine(reverseOriginalPosition, players[1].transform.position, Color.red);
// draw a line between current transform position and the next waypoint target
// each time reached a waypoint.
if (target != null)
Debug.DrawLine(target.transform.position, players[0].transform.position, Color.green);
if (reverseTarget != null)
Debug.DrawLine(reverseTarget.transform.position, players[1].transform.position, Color.green);
}
void AddColliderToWaypoints()
{
foreach (GameObject go in waypoints)
{
SphereCollider sc = go.AddComponent<SphereCollider>() as SphereCollider;
sc.isTrigger = true;
}
}
If you look at your RandomWayPointsAI() function, it only defines the index and the target but don't have any code below it to move the player.
private void WayPointsAI()
{
if (targetsIndex == waypoints.Length)
targetsIndex = 0;
target = waypoints[targetsIndex].transform;
float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);
void RandomWayPointsAI()
{
//No need to check if random is true anymore, you already checked when you run this function
int index = UnityEngine.Random.Range(0, waypoints.Length);
target = waypoints[index].transform;
//float distance = Vector3.Distance(players[0].transform.position, target.transform.position);
//players[0].transform.localRotation = Quaternion.Slerp(players[0].transform.localRotation, Quaternion.LookRotation(target.position - players[0].transform.localPosition), rotationSpeed * Time.deltaTime);**
}

How to access other classes from the Mouse Look Script

Can you help me access variables from other classes from the Mouse Look Script because I cant seem to seem to reference other classes (mainly the ones I created).
Any help would be appreciated.
private Quaternion m_CharacterTargetRot;
private Quaternion m_CameraTargetRot;
private bool m_cursorIsLocked = true;
private int LeftCounter ;
private int RightCounter;
public void Init(Transform character, Transform camera)
{
m_CharacterTargetRot = character.localRotation;
m_CameraTargetRot = camera.localRotation;
}
public void LookRotation(Transform character, Transform camera)
{
float yRot = CrossPlatformInputManager.GetAxis("Mouse X") * XSensitivity;
float xRot = CrossPlatformInputManager.GetAxis("Mouse Y") * YSensitivity;
m_CharacterTargetRot *= Quaternion.Euler (0f, yRot, 0f);
m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);
// Declaring focused rotations
Vector3 CharToTar = target.position - character.position;
Quaternion CharRotate = Quaternion.LookRotation (CharToTar);
if (WitchRotation) {
if (LeftCounter >= 50) {
LeftCounter = 0;
Debug.Log ("Witch Stare");
m_CharacterTargetRot = CharRotate;
m_CameraTargetRot *= Quaternion.Euler (-xRot, 0f, 0f);
}
character.rotation = m_CharacterTargetRot;
camera.localRotation = m_CameraTargetRot;
} else {
if (clampVerticalRotation)
m_CameraTargetRot = ClampRotationAroundXAxis (m_CameraTargetRot);
if (smooth) {
character.localRotation = Quaternion.Slerp (character.localRotation, m_CharacterTargetRot,
smoothTime * Time.deltaTime);
camera.localRotation = Quaternion.Slerp (camera.localRotation, m_CameraTargetRot,
smoothTime * Time.deltaTime);
} else {
character.localRotation = m_CharacterTargetRot;
camera.localRotation = m_CameraTargetRot;
}
}
// to detect rotation distance the camera rotated
if(Input.GetAxis("Mouse X") < 0){
LeftCounter++; //Left rotation distance
Debug.Log("Moved left " + LeftCounter + " times");
}
if(Input.GetAxis("Mouse X") > 0){
RightCounter++; //Right rotation distance
Debug.Log("Mouse right " + RightCounter + " times");
Debug.Log(RightCounter);
}
UpdateCursorLock();
}
public void SetCursorLock(bool value)
{
lockCursor = value;
if(!lockCursor)
{//we force unlock the cursor if the user disable the cursor locking helper
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
public void UpdateCursorLock()
{
//if the user set "lockCursor" we check & properly lock the cursos
if (lockCursor)
InternalLockUpdate();
}
private void InternalLockUpdate()
{
if(Input.GetKeyUp(KeyCode.Escape))
{
m_cursorIsLocked = false;
}
else if(Input.GetMouseButtonUp(0))
{
m_cursorIsLocked = true;
}
if (m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.Locked;
Cursor.visible = false;
}
else if (!m_cursorIsLocked)
{
Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;
}
}
Quaternion ClampRotationAroundXAxis(Quaternion q)
{
q.x /= q.w;
q.y /= q.w;
q.z /= q.w;
q.w = 1.0f;
float angleX = 2.0f * Mathf.Rad2Deg * Mathf.Atan (q.x);
angleX = Mathf.Clamp (angleX, MinimumX, MaximumX);
q.x = Mathf.Tan (0.5f * Mathf.Deg2Rad * angleX);
return q;
}
How to access other classes
Maybe you you are asking how to access variables/functions from another Class. The variable or function you want to access must be public not private.
public class ScriptA : MonoBehaviour{
public int playerScore = 0;
void Start()
{
}
public void doSomething()
{
}
}
Access variable playerScore in ScriptA from ScriptB.
public class ScriptB : MonoBehaviour{
ScriptA scriptInstance = null;
void Start()
{
GameObject tempObj = GameObject.Find("NameOfGameObjectScriptAIsAttachedTo");
scriptInstance = tempObj.GetComponent<ScriptA>();
//Access playerScore variable from ScriptA
scriptInstance.playerScore = 5;
//Call doSomething() function from ScriptA
scriptInstance.doSomething();
}
}

Adding Android Mobile Controller to Unity Game

I have been trying for quiet some time now to find out how can I place an android mobile game controller in Unity. The game I have is using the mouse and keyboard buttons to do that but because I want to publish it on Android as well I want to add mobile controllers and I am not very familiar with that.
Here is my PlayerController.cs:
public class PlayerControllerUnity : MonoBehaviour
{
public enum RotationAxes { MouseXAndY = 0, MouseX = 1, MouseY = 2 }
public RotationAxes axes = RotationAxes.MouseXAndY;
public float sensitivityX = 15.0f;
public float sensitivityY = 15.0f;
public float minimumX = -360.0f;
public float maximumX = 360.0f;
public float minimumY = -89.0f;
public float maximumY = 89.0f;
private float rotationYaxis = 0.0f;
private float rotationXaxis = 0.0f;
private Quaternion originalCameraRotation;
private Quaternion originalPlayerRotation;
public PlayerUnity playerUnity;
private GameObject hand;
private GameObject goInHand;
private CWObject currentObjectInHand;
private Vector3 positionHand_Tile = new Vector3(0.15f, -0.15f, 0.3f);
private Vector3 scaleHand_Tile = new Vector3(0.1f, 0.1f, 0.1f);
private Quaternion rotationHand_Tile = Quaternion.Euler(-15.0f, 0.0f, 15.0f);
private Vector3 positionHand_Item = new Vector3(0.15f, -0.15f, 0.2f);
private Vector3 scaleHand_Item = new Vector3(0.1f, 0.1f, 0.1f);
private Quaternion rotationHand_Item = Quaternion.Euler(0.0f, 55.0f, 0.0f);
private Vector3 positionHand_Current;
private Vector3 scaleHand_Current;
private Quaternion rotationHand_Current;
private bool firstUpdate = true;
public void Start()
{
originalCameraRotation = playerUnity.mainCamera.transform.localRotation;
originalPlayerRotation = transform.localRotation;
hand = new GameObject();
hand.name = "Hand";
hand.transform.parent = playerUnity.mainCamera.transform;
hand.transform.localPosition = positionHand_Tile;
hand.transform.localScale = scaleHand_Tile;
hand.transform.localRotation = rotationHand_Tile;
}
public void UpdateControlled()
{
if (playerUnity.gameManagerUnity.State == GameManagerUnity.GameManagerUnityState.GAME &&
playerUnity.playerGUI.ActiveState == PlayerGUI.State.NORMAL)
{
if (Screen.lockCursor == false)
{
//Auto pause if the user leaves the game for some reason (ALT+TAB, etc..)
playerUnity.gameManagerUnity.Pause();
}
else
{
if (firstUpdate)
{
rotationYaxis = playerUnity.player.rotation.y;
rotationXaxis = playerUnity.player.rotation.x;
firstUpdate = false;
}
if (Input.GetKeyDown(KeyCode.R))
playerUnity.player.ResetPosition();
if (Input.GetKeyDown(KeyCode.C))
playerUnity.ChangeCamera();
UpdateJump();
UpdateMovement();
UpdateCameraRotation();
UpdateUserActions();
UpdateItemOnHand();
playerUnity.player.rotation.y = rotationYaxis;
playerUnity.player.rotation.x = rotationXaxis;
}
}
}
private void ExecuteHandUseAnimation()
{
handUseAnimationTimer = 0.5f;
}
private float handUseAnimationTimer;
private float handMovementTimer;
private void UpdateItemOnHand()
{
if (currentObjectInHand != playerUnity.objectInHand)
{
if (goInHand)
{
playerUnity.gameManagerUnity.objectsManagerUnity.RemoveGameObject(goInHand);
goInHand = null;
}
this.currentObjectInHand = playerUnity.objectInHand;
if (currentObjectInHand != null)
{
goInHand = playerUnity.gameManagerUnity.objectsManagerUnity.CreateGameObjectFromObject(currentObjectInHand);
goInHand.transform.parent = hand.transform;
goInHand.transform.localScale = new Vector3(1, 1, 1);
goInHand.transform.localPosition = new Vector3(0, 0, 0);
goInHand.transform.localRotation = Quaternion.identity;
switch (currentObjectInHand.definition.type)
{
case CWDefinition.DefinitionType.Item:
positionHand_Current = positionHand_Item;
scaleHand_Current = scaleHand_Item;
rotationHand_Current = rotationHand_Item;
break;
case CWDefinition.DefinitionType.Tile:
positionHand_Current = positionHand_Tile;
scaleHand_Current = scaleHand_Tile;
rotationHand_Current = rotationHand_Tile;
break;
}
hand.transform.localPosition = positionHand_Current;
hand.transform.localScale = scaleHand_Current;
hand.transform.localRotation = rotationHand_Current;
}
}
if (handUseAnimationTimer <= 0.0f)
{
if (playerUnity.player.input.moveDirection.magnitude > 0.0f)
{
handMovementTimer += Time.deltaTime;
float deltaY = Mathf.Sin(handMovementTimer * 10) * 0.02f;
float deltaX = Mathf.Sin(handMovementTimer * 10) * 0.01f;
hand.transform.localPosition = positionHand_Current + new Vector3(deltaX, deltaY, 0.0f);
}
else
{
handMovementTimer = 0.0f;
hand.transform.localPosition = positionHand_Current;
}
}
else
{
if (currentObjectInHand != null)
{
float deltaRotation = Mathf.Sin(handUseAnimationTimer * 2.0f * Mathf.PI) * 30;
hand.transform.localPosition = positionHand_Current;
switch (currentObjectInHand.definition.type)
{
case CWDefinition.DefinitionType.Tile:
hand.transform.localRotation = rotationHand_Current * Quaternion.Euler(deltaRotation, 0, 0);
break;
case CWDefinition.DefinitionType.Item:
hand.transform.localRotation = rotationHand_Current * Quaternion.Euler(0, 0, deltaRotation);
break;
}
}
handUseAnimationTimer -= Time.deltaTime;
if (handUseAnimationTimer <= 0.0f)
{
hand.transform.localRotation = rotationHand_Current;
handUseAnimationTimer = 0.0f;
}
}
}
private float userActionCooldown;
private void UpdateUserActions()
{
if (playerUnity.gameManagerUnity.State == GameManagerUnity.GameManagerUnityState.GAME ||
playerUnity.gameManagerUnity.State == GameManagerUnity.GameManagerUnityState.PAUSE)
{
Vector3 cameraPos = playerUnity.transform.position + playerUnity.GetLocalHeadPosition();
Vector3 cameraFwd = playerUnity.mainCamera.transform.forward;
CubeWorld.Utils.Graphics.RaycastTileResult raycastResult = CubeWorld.Utils.Graphics.RaycastTile(
playerUnity.player.world,
GraphicsUnity.Vector3ToCubeWorldVector3(cameraPos),
GraphicsUnity.Vector3ToCubeWorldVector3(cameraFwd),
10.0f,
true, false);
if (userActionCooldown > 0.0f)
userActionCooldown -= Time.deltaTime;
if (userActionCooldown <= 0.0f)
{
if (Input.GetMouseButton(0) || Input.GetMouseButton(1))
{
ExecuteHandUseAnimation();
userActionCooldown = 0.2f;
}
if (raycastResult.hit)
{
if (Input.GetMouseButton(0))
{
if (raycastResult.position.x > 0 && raycastResult.position.x < playerUnity.player.world.tileManager.sizeX - 1 &&
raycastResult.position.z > 0 && raycastResult.position.z < playerUnity.player.world.tileManager.sizeZ - 1 &&
raycastResult.position.y > 0)
{
if (playerUnity.player.world.tileManager.HasTileActions(
raycastResult.position,
TileActionRule.ActionType.CLICKED))
{
playerUnity.player.world.gameplay.TileClicked(raycastResult.position);
}
else
{
if (playerUnity.objectInHand != null)
{
switch (playerUnity.objectInHand.definition.type)
{
case CWDefinition.DefinitionType.Item:
{
playerUnity.gameManagerUnity.fxManagerUnity.PlaySound("hitmetal", playerUnity.player.position);
playerUnity.player.world.gameplay.TileHit(raycastResult.position, ((Item)playerUnity.objectInHand).itemDefinition);
break;
}
default:
playerUnity.gameManagerUnity.fxManagerUnity.PlaySound("hit", playerUnity.player.position);
playerUnity.player.world.tileManager.DamageTile(raycastResult.position, 1);
break;
}
}
}
}
}
else if (Input.GetMouseButton(1))
{
if (playerUnity.objectInHand != null && playerUnity.objectInHand.definition.type == CWDefinition.DefinitionType.Tile)
{
TileDefinition tileDefinition = (TileDefinition) playerUnity.objectInHand.definition;
TilePosition tileCreatePosition = raycastResult.position + CubeWorld.Utils.Graphics.GetFaceNormal(raycastResult.face);
//Don't create tile on top of the world, because no triangles are drawn on the border!
if (tileCreatePosition.y < playerUnity.player.world.tileManager.sizeY - 1 &&
playerUnity.player.world.tileManager.IsValidTile(tileCreatePosition) &&
playerUnity.player.world.tileManager.GetTileSolid(tileCreatePosition) == false)
{
if (playerUnity.player.world.avatarManager.IsTileBlockedByAnyAvatar(tileCreatePosition) == false)
{
playerUnity.player.world.gameplay.CreateTile(tileCreatePosition, tileDefinition.tileType);
playerUnity.player.inventory.RemoveFromDefinition(tileDefinition, 1);
if (playerUnity.player.inventory.HasMoreOfDefinition(tileDefinition) == false)
playerUnity.objectInHand = null;
}
}
}
}
}
}
}
}
private void UpdateJump()
{
playerUnity.player.input.jump = Input.GetKey(KeyCode.Space);
}
private void UpdateMovement()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
Vector3 dirWalk = transform.forward * v;
Vector3 dirStrafe = transform.right * h;
Vector3 dir = dirWalk + dirStrafe;
dir.y = 0;
dir.Normalize();
playerUnity.player.input.moveDirection = GraphicsUnity.Vector3ToCubeWorldVector3(dir);
}
private void UpdateCameraRotation()
{
if (Screen.lockCursor)
{
if (axes == RotationAxes.MouseXAndY)
{
// Read the mouse input axis
rotationYaxis += Input.GetAxis("Mouse X") * sensitivityX;
rotationXaxis += Input.GetAxis("Mouse Y") * sensitivityY;
rotationYaxis = ClampAngle(rotationYaxis, minimumX, maximumX);
rotationXaxis = ClampAngle(rotationXaxis, minimumY, maximumY);
Quaternion xQuaternion = Quaternion.AngleAxis(rotationYaxis, Vector3.up);
Quaternion yQuaternion = Quaternion.AngleAxis(rotationXaxis, Vector3.left);
playerUnity.mainCamera.transform.localRotation = originalCameraRotation * yQuaternion;
transform.localRotation = originalPlayerRotation * xQuaternion;
}
else if (axes == RotationAxes.MouseX)
{
rotationYaxis += Input.GetAxis("Mouse X") * sensitivityX;
rotationYaxis = ClampAngle(rotationYaxis, minimumX, maximumX);
Quaternion xQuaternion = Quaternion.AngleAxis(rotationYaxis, Vector3.up);
transform.localRotation = originalPlayerRotation * xQuaternion;
}
else
{
rotationXaxis += Input.GetAxis("Mouse Y") * sensitivityY;
rotationXaxis = ClampAngle(rotationXaxis, minimumY, maximumY);
Quaternion yQuaternion = Quaternion.AngleAxis(rotationXaxis, Vector3.left);
playerUnity.mainCamera.transform.localRotation = originalCameraRotation * yQuaternion;
}
}
}
public static float ClampAngle(float angle, float min, float max)
{
if (angle < -360F)
angle += 360F;
if (angle > 360F)
angle -= 360F;
return Mathf.Clamp(angle, min, max);
}
}
Honestly this is a question best asked here.
However, being that it is unity I'm almost 100% sure that there is a built in controller script for android available to you as an option when you try to create a new project.
It sounds like you are creating something for PC and Android? Unless I am reading that incorrectly.
Either way there is definitely a controller script pre-made in Unity for PC projects and probably for android ones as well.

2D Character falls off the map in Unity3D

I am currently working on a project for one of the courses i am taking.
I am making a 2D game in unity3D, and i have a small problem, every time i run the game my character keeps on falling through the map, even though i have added a rigidbody2D and a boxCollider2D to both my character and the foreground. The code is attached, it is in C# and it is a bit long. Thank you so much in advance ..
enter code here
using System;
using UnityEngine;
using System.Collections;
public class CharacterController2D : MonoBehaviour
{
private const float SkinWidth = .02f;
private const int TotalHorizontalRays = 8;
private const int TotalVerticalRays = 4;
private static readonly float SlopeLimitTanget = Mathf.Tan (75f * Mathf.Deg2Rad);
public LayerMask PlatformMask;
public ControllerParameters2D DefaultParameters;
public ControllerState2D State { get; private set; }
public Vector2 Velocity { get { return _velocity; }}
public bool HandleCollisions { get; set; }
//Return overrideparamteres if it is not null, if it is null it will return DefaultParameters
public ControllerParameters2D Parameters { get { return _overrideParameters ?? DefaultParameters; } }
public GameObject StandingOn { get; private set;}
public Vector3 PlatformVelocity { get; private set;}
public bool CanJump
{
get
{
if(Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpAnywhere)
return _jumpIn <= 0;
if(Parameters.JumpRestrictions == ControllerParameters2D.JumpBehavior.CanJumpOnGround)
return State.IsGrounded;
return false;
}
}
private Vector2 _velocity;
private Transform _transform;
private Vector3 _localScale;
private BoxCollider2D _boxCollider;
private ControllerParameters2D _overrideParameters;
private float _jumpIn;
private GameObject _lastStandingOn;
private Vector3
_activeGlobalPlatformPoint,
_activeLocalPlatformPoint;
private Vector3
_raycastTopLeft,
_raycastBottomRight,
_raycastBottomLeft;
private float _verticalDistanceBetweenRays,
_horizonatalDistanceBetweenRays;
public void Awake()
{
HandleCollisions = true;
State = new ControllerState2D();
_transform = transform;
_localScale = transform.localScale;
_boxCollider = GetComponent <BoxCollider2D>();
// Absolute Value
var colliderWidth = _boxCollider.size.x * Mathf.Abs(transform.localScale.x) - (2 * SkinWidth);
_horizonatalDistanceBetweenRays = colliderWidth / (TotalVerticalRays - 1);
var colliderHeight = _boxCollider.size.y * Mathf.Abs( transform.localScale.y ) - (2 * SkinWidth);
_verticalDistanceBetweenRays = colliderHeight / (TotalHorizontalRays - 1);
}
public void AddForce(Vector2 force)
{
_velocity = force;
}
public void SetForce(Vector2 force)
{
_velocity += force;
}
public void SetHorizontalForce(float x)
{
_velocity.x = x;
}
public void SetVerticalForce(float y)
{
_velocity.y = y;
}
public void Jump()
{
AddForce(new Vector2(0, Parameters.JumpMagnitude));
_jumpIn = Parameters.JumpFrequency;
}
public void LateUpdate()
{
_jumpIn -= Time.deltaTime;
//We force the player to go up or down based on the gravity
_velocity.y += Parameters.Gravity * Time.deltaTime;
//Move the characther per his velocity scaled by time
Move (Velocity * Time.deltaTime);
}
// Ensures the player doesn't fall off the map or move through the wall
private void Move(Vector2 deltaMovement)
{
var wasGrounded = State.IsCollidingBelow;
State.Reset();
if(HandleCollisions)
{
HandlePlatforms();
CalculateRayOrigins();
if(deltaMovement.y < 0 && wasGrounded)
HandleVerticalSlope(ref deltaMovement);
if(Mathf.Abs(deltaMovement.x) > .001f)
MoveHorizontally(ref deltaMovement);
MoveVertically(ref deltaMovement);
CorrectHorizontalPlacement(ref deltaMovement, true);
CorrectHorizontalPlacement(ref deltaMovement, false);
}
_transform.Translate(deltaMovement, Space.World);
if (Time.deltaTime > 0)
_velocity = deltaMovement / Time.deltaTime;
_velocity.x = Mathf.Min (_velocity.x, Parameters.MaxVelocity.x);
_velocity.y = Mathf.Min (_velocity.y, Parameters.MaxVelocity.y);
if(State.IsMovingUpSlope)
_velocity.y = 0;
//Standing on the platform
if(StandingOn != null)
{
_activeGlobalPlatformPoint = transform.position;
_activeLocalPlatformPoint = StandingOn.transform.InverseTransformPoint(transform.position);
Debug.DrawLine(transform.position, _activeGlobalPlatformPoint);
Debug.DrawLine(transform.position, _activeLocalPlatformPoint + StandingOn.transform.position);
if(_lastStandingOn != StandingOn)
{
//If the last thing we are standing on is not null, send a message to leave it
if(_lastStandingOn != null)
_lastStandingOn.SendMessage("ControllerExist2D", this, SendMessageOptions.DontRequireReceiver);
//Inform what we are standing on that we have entered
StandingOn.SendMessage("ControllerEnter2D", this, SendMessageOptions.DontRequireReceiver);
_lastStandingOn = StandingOn;
}
//Invoke the platform that we are standing on it
else if (StandingOn != null)
StandingOn.SendMessage("ControllerStay2D", this, SendMessageOptions.DontRequireReceiver);
}
else if (_lastStandingOn != null)
{
_lastStandingOn.SendMessage("ControllerExit2D", this, SendMessageOptions.DontRequireReceiver);
_lastStandingOn = null;
}
}
private void HandlePlatforms()
{
//Calculate the velocity of the platform
if(StandingOn != null)
{
var newGlobalPlatformPoint = StandingOn.transform.TransformPoint(_activeLocalPlatformPoint);
var moveDistance = newGlobalPlatformPoint - _activeGlobalPlatformPoint;
//Sticks the player on the platform, wherever the platform teleport the players stays on it
if(moveDistance != Vector3.zero)
transform.Translate(moveDistance, Space.World);
PlatformVelocity = (newGlobalPlatformPoint - _activeGlobalPlatformPoint) / Time.deltaTime;
}
else
PlatformVelocity = Vector3.zero;
StandingOn = null;
}
private void CorrectHorizontalPlacement(ref Vector2 deltaMovement, bool isRight)
{
var halfwidth = (_boxCollider.size.x * _localScale.x) / 2f;
var rayOrigin = isRight ? _raycastBottomRight : _raycastBottomLeft;
if(isRight)
rayOrigin.x -= (halfwidth - SkinWidth);
else
rayOrigin.x += (halfwidth - SkinWidth);
var rayDirection = isRight ? Vector2.right : -Vector2.right;
var offset = 0f;
for(var i = 1; i <= TotalHorizontalRays - 1; i++)
{
var rayVector = new Vector2(deltaMovement.x + rayOrigin.x, deltaMovement.y + rayOrigin.y + (i * _verticalDistanceBetweenRays));
Debug.DrawRay(rayVector, rayDirection * halfwidth, isRight ? Color.cyan : Color.magenta);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, halfwidth, PlatformMask);
if(!raycastHit)
continue;
offset = isRight ? ((raycastHit.point.x - _transform.position.x) - halfwidth) : (halfwidth - (_transform.position.x - raycastHit.point.x));
}
deltaMovement.x += offset;
}
private void CalculateRayOrigins()
{
var size = new Vector2 (_boxCollider.size.x * Mathf.Abs (_localScale.x), _boxCollider.size.y * Mathf.Abs (_localScale.y)) / 2;
var center = new Vector2(_boxCollider.center.x * _localScale.x, _boxCollider.center.y * _localScale.y);
//Location of the player, then we add the box collider to it relative to the center of the player
_raycastTopLeft = _transform.position + new Vector3 (center.x - size.x + SkinWidth, center.y + size.y - SkinWidth);
_raycastBottomRight = _transform.position + new Vector3 (center.x + size.x - SkinWidth, center.y - size.y + SkinWidth); //Going right
_raycastBottomLeft = _transform.position + new Vector3 (center.x - size.x + SkinWidth, center.y - size.y + SkinWidth); //Going left and down-up
}
//Cast rays to the left or to the right depending on the player's movement
//Determining how far the player can go either to the left, or to the right
private void MoveHorizontally(ref Vector2 deltaMovement)
{
var isGoingRight = deltaMovement.x > 0;
//The distance between the starting point and the final destination
var rayDistance = Mathf.Abs (deltaMovement.x) + SkinWidth;
//Where is the player going? right or left
var rayDirection = isGoingRight ? Vector2.right : -Vector2.right;
//Right? we start from bottom right. Left? we start fro, bottom left
var rayOrigin = isGoingRight ? _raycastBottomRight : _raycastBottomLeft;
//Determines how many rays we want to shoot out to the left or to the right
for(var i = 0; i < TotalHorizontalRays; i++)
{
var rayVector = new Vector2(rayOrigin.x, rayOrigin.y + (i * _verticalDistanceBetweenRays));
//Visual representation about the rays
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
//Checks if the player hit something or not
var rayCastHit = Physics2D.Raycast(rayVector, rayOrigin, rayDistance, PlatformMask);
if(!rayCastHit) //If there was a raycast then do something, otherwise continue to loop
continue;
//We return true if we are on a horizotnal slope, and check if we are going right or left or hit something while going up
if(i == 0 && HandleHorizontalSlope(ref deltaMovement, Vector2.Angle(rayCastHit.normal, Vector2.up), isGoingRight))
break;
//If we hit something then we can only go that far forward
deltaMovement.x = rayCastHit.point.x - rayVector.x;
rayDistance = Mathf.Abs(deltaMovement.x);
if(isGoingRight)
{
//If we are going right, then we have to substract the skinwidth
deltaMovement.x -= SkinWidth;
State.IsCollidingRight = true;
}
else
{
//The oppoiste of the if statement, if we are going left, we add the skinwidth
deltaMovement.x += SkinWidth;
State.IsCollidingLeft = true;
}
//Handles error collision, if the player hits something and go through it
if(rayDistance < SkinWidth + .0001f)
break;
}
}
private void MoveVertically(ref Vector2 deltaMovement)
{
//Check to see if going up or down
var isGoingUp = deltaMovement.y > 0;
var rayDistance = Mathf.Abs (deltaMovement.y) + SkinWidth;
var rayDirection = isGoingUp ? Vector2.up : -Vector2.up;
var rayOrigin = isGoingUp ? _raycastTopLeft : _raycastBottomLeft;
rayOrigin.x += deltaMovement.x;
var standingOnDistance = float.MaxValue;
for(var Count = 0; Count < TotalVerticalRays; Count++)
{
var rayVector = new Vector2(rayOrigin.x + (Count * _horizonatalDistanceBetweenRays), rayOrigin.y);
Debug.DrawRay(rayVector, rayDirection * rayDistance, Color.red);
var raycastHit = Physics2D.Raycast(rayVector, rayDirection, rayDistance, PlatformMask);
//If the player hit nothing then keep going.
if(raycastHit)
{
continue;
}
if(!isGoingUp)
{
var verticalDistanceToHit = _transform.position.y - raycastHit.point.y;
if(verticalDistanceToHit < standingOnDistance)
{
standingOnDistance = verticalDistanceToHit;
//Platform we are standing on
StandingOn = raycastHit.collider.gameObject;
}
}
//Determine the furthest distance we can move down or up without hitting anything
deltaMovement.y = raycastHit.point.y - rayVector.y;
rayDistance = Mathf.Abs(deltaMovement.y);
if(isGoingUp)
{
deltaMovement.y -= SkinWidth;
State.IsCollidingAbove = true;
}
else
{
deltaMovement.y += SkinWidth;
State.IsCollidingBelow = true;
}
if(!isGoingUp && deltaMovement.y > .0001f)
{
State.IsMovingUpSlope = true;
}
if(rayDistance < SkinWidth + .0001f)
{
break;
}
}
}
private void HandleVerticalSlope(ref Vector2 deltaMovement)
{
//Give us the center of the vertical rays;
var center = (_raycastBottomLeft.x + _raycastBottomRight.x) / 2;
var direction = -Vector2.up;
var slopeDistance = SlopeLimitTanget * (_raycastBottomRight.x - center);
var slopeRayVector = new Vector2 (center, _raycastBottomLeft.y);
Debug.DrawRay(slopeRayVector, direction * slopeDistance, Color.yellow);
var raycastHit = Physics2D.Raycast (slopeRayVector, direction, slopeDistance, PlatformMask);
if (!raycastHit)
return;
// ReSharper disable CompareOfFloatsByEqualityOperator
var isMovingDownSlope = Mathf.Sign (raycastHit.normal.x) == Mathf.Sign (deltaMovement.x);
if(!isMovingDownSlope)
return;
var angle = Vector2.Angle (raycastHit.normal, Vector2.up);
if(Mathf.Abs(angle) < .0001f)
return; //Which means there we are not on a slope, we are on something else
State.IsMovingDownSlope = true;
State.SlopeAngle = angle;
deltaMovement.y = raycastHit.point.y - slopeRayVector.y;
}
private bool HandleHorizontalSlope(ref Vector2 deltaMovement, float angle, bool isGoingRight)
{
//We do not want to move to an angle of 90
if(Mathf.RoundToInt(angle) == 90)
return false;
if(angle > Parameters.SlopeLimit)
{
deltaMovement.x = 0;
return true;
}
if(deltaMovement.y > .07f)
return true;
deltaMovement.x += isGoingRight ? -SkinWidth : SkinWidth;
deltaMovement.y = Mathf.Abs (Mathf.Tan (angle * Mathf.Deg2Rad) * deltaMovement.x);
State.IsMovingUpSlope = true;
State.IsCollidingBelow = true;
return true;
}
public void OnTriggerEnter2D(Collider2D other)
{
var parameters = other.gameObject.GetComponent<ControllerPhysicsVolume2D>();
if(parameters == null)
return;
_overrideParameters = parameters.Parameters;
}
public void OnTriggerExit2D(Collider2D other)
{
var parameters = other.gameObject.GetComponent<ControllerPhysicsVolume2D>();
if(parameters == null)
return;
_overrideParameters = null;
}
}
As #Terrance said you really don't need to write your own code logic for collision detection.
Secondly I noticed OnTriggerEnter2D and OnTriggerExit2D methods in your code, that also points out to one thing that all your boxCollider2d has isTrigger option checked. Therefore, I suggest you to uncheck isTrigger option on both your player and ground as TRIGGER will never stop two objects from crossing each other (you need to have both objects have 'isTrigger' unchecked on their colliders if you don't want them to pass through each other). And use method OnCollisionEnter2D and OnCollisionExit2D to detect the collision.
What is difference between Trigger and a Collider:
Taking real world example Colliders are tangible object e.g you yourself and the floor you are standing on both are solid and tangible.
While trigger is intangible, example of triggers can be the walkthrough security doors; these doors are hollow from inside allowing any person to pass without any hindrance, but if you wear any metal object on yourself and pass through that "Hollow Area" between the door, the door will TRIGGER an alarm. therefore with respect to the game world you can say that the door has a trigger at it hollow area.

Categories