I am having a problem with my RTS game where my enemy units will not attack any base buildings I create after the level starts. They go to attack every other building that was there when the level starts, but none of the built ones.
There is a list being set up of the closest targets to units and they will go to attack their closest target, but any newly instantiated buildings or units, don't get attacked for some reason.
The function DecideWhatToDo() is called on all units in the WorldObject script when they are not doing anything. It then calls FindNearbyObjects() from the WorkManager script.
Everything works up until new units and buildings are created, has anyone experienced this kind of problem before?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
using RTS;
public class WorldObject : MonoBehaviour {
BoxCollider boxCollider;
bool isDead;
bool isSinking;
public string objectName;
public Texture2D buildImage;
public int cost, sellValue, maxHitPoints;
public float hitPoints;
public virtual bool IsActive { get { return true; } }
public float weaponRange = 10.0f;
public float weaponRechargeTime = 1.0f;
public float weaponAimSpeed = 1.0f;
public AudioClip attackSound, selectSound, useWeaponSound;
public float attackVolume = 1.0f, selectVolume = 1.0f, useWeaponVolume = 1.0f;
public int ObjectId { get; set; }
public float detectionRange = 20.0f;
public GameObject explosionPrefab, splat;
protected NavMeshAgent agent;
protected AudioElement audioElement;
protected Animator anim;
protected List<WorldObject> nearbyObjects;
protected Rect playingArea = new Rect(0.0f, 0.0f, 0.0f, 0.0f);
protected Player player;
protected string[] actions = { };
protected bool currentlySelected = false;
protected Bounds selectionBounds;
protected GUIStyle healthStyle = new GUIStyle();
protected float healthPercentage = 1.0f;
protected WorldObject target = null;
protected bool attacking = false;
protected bool movingIntoPosition = false;
protected bool aiming = false;
private List<Material> oldMaterials = new List<Material>();
private float currentWeaponChargeTime;
//we want to restrict how many decisions are made to help with game performance
//the default time at the moment is a tenth of a second
private float timeSinceLastDecision = 0.0f, timeBetweenDecisions = 0.1f;
protected virtual void Awake()
{
anim = GetComponent<Animator>();
boxCollider = GetComponent<BoxCollider>();
selectionBounds = ResourceManager.InvalidBounds;
CalculateBounds();
}
protected virtual void Start()
{
agent = GetComponent<NavMeshAgent>();
SetPlayer();
if (player) SetTeamColor();
InitialiseAudio();
}
protected virtual void Update()
{
if (isSinking)
{
this.transform.Translate(-Vector3.up * 2.5f * Time.deltaTime);
}
if (ShouldMakeDecision()) DecideWhatToDo();
currentWeaponChargeTime += Time.deltaTime;
if (attacking && !movingIntoPosition && !aiming)
{
PerformAttack();
}
}
/**
* A child class should only determine other conditions under which a decision should
* not be made. This could be 'harvesting' for a harvester, for example. Alternatively,
* an object that never has to make decisions could just return false.
*/
protected virtual bool ShouldMakeDecision()
{
if (!attacking && !movingIntoPosition && !aiming)
{
//we are not doing anything at the moment
if (timeSinceLastDecision > timeBetweenDecisions)
{
timeSinceLastDecision = 0.0f;
Debug.Log("");
return true;
}
timeSinceLastDecision += Time.deltaTime;
}
return false;
}
protected virtual void DecideWhatToDo()
{
//determine what should be done by the world object at the current point in time
Vector3 currentPosition = transform.position;
nearbyObjects = WorkManager.FindNearbyObjects(currentPosition, detectionRange);
if (CanAttack())
{
List<WorldObject> enemyObjects = new List<WorldObject>();
foreach (WorldObject nearbyObject in nearbyObjects)
{
Resource resource = nearbyObject.GetComponent<Resource>();
if (resource) continue;
if (nearbyObject.GetPlayer() != player) enemyObjects.Add(nearbyObject);
}
WorldObject closestObject = WorkManager.FindNearestWorldObjectInListToPosition(enemyObjects, currentPosition);
if (closestObject)
{
attacking = true;
//agent.isStopped = true;
BeginAttack(closestObject);
}
}
}
public Player GetPlayer()
{
return player;
}
protected virtual void OnGUI()
{
if (currentlySelected && !ResourceManager.MenuOpen) DrawSelection();
}
protected virtual void InitialiseAudio()
{
List<AudioClip> sounds = new List<AudioClip>();
List<float> volumes = new List<float>();
if (attackVolume < 0.0f) attackVolume = 0.0f;
if (attackVolume > 1.0f) attackVolume = 1.0f;
sounds.Add(attackSound);
volumes.Add(attackVolume);
if (selectVolume < 0.0f) selectVolume = 0.0f;
if (selectVolume > 1.0f) selectVolume = 1.0f;
sounds.Add(selectSound);
volumes.Add(selectVolume);
if (useWeaponVolume < 0.0f) useWeaponVolume = 0.0f;
if (useWeaponVolume > 1.0f) useWeaponVolume = 1.0f;
sounds.Add(useWeaponSound);
volumes.Add(useWeaponVolume);
audioElement = new AudioElement(sounds, volumes, objectName + ObjectId, this.transform);
}
public void SetPlayer()
{
player = transform.root.GetComponentInChildren<Player>();
}
public bool IsOwnedBy(Player owner)
{
if (player && player.Equals(owner))
{
return true;
}
else
{
return false;
}
}
public void CalculateBounds()
{
selectionBounds = new Bounds(transform.position, Vector3.zero);
foreach (Renderer r in GetComponentsInChildren<Renderer>())
{
selectionBounds.Encapsulate(r.bounds);
}
}
//!!!!!MULTI SELECTION!!!!!
public virtual void SetSelection(bool selected, Rect playingArea)
{
currentlySelected = selected;
if (selected)
{
if (audioElement != null) audioElement.Play(selectSound);
this.playingArea = playingArea;
}
CalculateBounds();
}
//!!!!!MULTI SELECTION!!!!!
public Bounds GetSelectionBounds()
{
return selectionBounds;
}
public string[] GetActions()
{
return actions;
}
public void SetColliders(bool enabled)
{
Collider[] colliders = GetComponentsInChildren<Collider>();
foreach (Collider collider in colliders) collider.enabled = enabled;
}
public void SetTransparentMaterial(Material material, bool storeExistingMaterial)
{
if (storeExistingMaterial) oldMaterials.Clear();
Renderer[] renderers = GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
if (storeExistingMaterial) oldMaterials.Add(renderer.material);
renderer.material = material;
}
}
public void RestoreMaterials()
{
Renderer[] renderers = GetComponentsInChildren<Renderer>();
if (oldMaterials.Count == renderers.Length)
{
for (int i = 0; i < renderers.Length; i++)
{
renderers[i].material = oldMaterials[i];
}
}
}
public void SetPlayingArea(Rect playingArea)
{
this.playingArea = playingArea;
}
public virtual void SetHoverState(GameObject hoverObject)
{
//only handle input if owned by a human player and currently selected
if (player && player.human && currentlySelected)
{
//something other than the ground is being hovered over
if (hoverObject.name != "Ground")
{
Player owner = hoverObject.transform.root.GetComponent<Player>();
Unit unit = hoverObject.transform.parent.GetComponent<Unit>();
Building building = hoverObject.transform.parent.GetComponent<Building>();
if (owner)
{ //the object is owned by a player
if (owner.username == player.username) player.hud.SetCursorState(CursorState.Select);
else if (CanAttack()) player.hud.SetCursorState(CursorState.Attack);
else player.hud.SetCursorState(CursorState.Select);
}
else if (unit || building && CanAttack()) player.hud.SetCursorState(CursorState.Attack);
else player.hud.SetCursorState(CursorState.Select);
}
}
}
public virtual bool CanAttack()
{
//default behaviour needs to be overidden by children
return false;
}
public virtual void PerformAction(string actionToPerform)
{
//it is up to children with specific actions to determine what to do with each of those actions
}
public virtual void MouseClick(GameObject hitObject, Vector3 hitPoint, Player controller)
{
//only handle input if currently selected
if (currentlySelected && hitObject && hitObject.name != "Ground")
{
WorldObject worldObject = hitObject.transform.parent.GetComponent<WorldObject>();
//clicked on another selectable object
if (worldObject)
{
Resource resource = hitObject.transform.parent.GetComponent<Resource>();
if (resource && resource.isEmpty()) return;
Player owner = hitObject.transform.root.GetComponent<Player>();
if (owner)
{ //the object is controlled by a player
if (player && player.human)
{ //this object is controlled by a human player
//start attack if object is not owned by the same player and this object can attack, else select
if (player.username != owner.username && CanAttack())
{
BeginAttack(worldObject);
}
else ChangeSelection(worldObject, controller);
}
else ChangeSelection(worldObject, controller);
}
else ChangeSelection(worldObject, controller);
}
}
}
protected virtual void BeginAttack(WorldObject target)
{
//if (audioElement != null) audioElement.Play(attackSound);
this.target = target;
if (TargetInRange())
{
anim.SetBool("Attacking", true);
attacking = true;
PerformAttack();
}
else AdjustPosition();
}
protected void SetTeamColor()
{
TeamColor[] teamColors = GetComponentsInChildren<TeamColor>();
foreach (TeamColor teamColor in teamColors) teamColor.GetComponent<Renderer>().material.color = player.teamColor;
}
protected virtual void DrawSelectionBox(Rect selectBox)
{
GUI.Box(selectBox, "");
CalculateCurrentHealth(0.35f, 0.65f);
DrawHealthBar(selectBox, "");
}
protected virtual void CalculateCurrentHealth(float lowSplit, float highSplit)
{
healthPercentage = (float)hitPoints / (float)maxHitPoints;
if (healthPercentage > highSplit) healthStyle.normal.background = ResourceManager.HealthyTexture;
else if (healthPercentage > lowSplit) healthStyle.normal.background = ResourceManager.DamagedTexture;
else healthStyle.normal.background = ResourceManager.CriticalTexture;
}
protected void DrawHealthBar(Rect selectBox, string label)
{
healthStyle.padding.top = -20;
healthStyle.fontStyle = FontStyle.Bold;
GUI.Label(new Rect(selectBox.x, selectBox.y - 7, selectBox.width * healthPercentage, 5), label, healthStyle);
}
protected virtual void AimAtTarget()
{
aiming = true;
//this behaviour needs to be specified by a specific object
}
private void ChangeSelection(WorldObject worldObject, Player controller)
{
//this should be called by the following line, but there is an outside chance it will not
SetSelection(false, playingArea);
if (controller.SelectedObject) controller.SelectedObject.SetSelection(false, playingArea);
controller.SelectedObject = worldObject;
worldObject.SetSelection(true, controller.hud.GetPlayingArea());
}
private void DrawSelection()
{
GUI.skin = ResourceManager.SelectBoxSkin;
Rect selectBox = WorkManager.CalculateSelectionBox(selectionBounds, playingArea);
//Draw the selection box around the currently selected object, within the bounds of the playing area
GUI.BeginGroup(playingArea);
DrawSelectionBox(selectBox);
GUI.EndGroup();
}
private bool TargetInRange()
{
Vector3 targetLocation = target.transform.position;
Vector3 direction = targetLocation - transform.position;
if (direction.sqrMagnitude < weaponRange * weaponRange)
{
return true;
}
return false;
}
private void AdjustPosition()
{
Unit self = this as Unit;
if (self)
{
movingIntoPosition = true;
Vector3 attackPosition = FindNearestAttackPosition();
self.StartMove(attackPosition);
attacking = true;
}
else
{
attacking = false;
}
}
private Vector3 FindNearestAttackPosition()
{
Vector3 targetLocation = target.transform.position;
Vector3 direction = targetLocation - transform.position;
float targetDistance = direction.magnitude;
float distanceToTravel = targetDistance - (0.9f * weaponRange);
return Vector3.Lerp(transform.position, targetLocation, distanceToTravel / targetDistance);
}
private void PerformAttack()
{
if (!target)
{
attacking = false;
anim.SetBool("Attacking", false);
anim.SetBool("IsRunning", false);
return;
}
if (!TargetInRange())
{
AdjustPosition();
}
else if (!TargetInFrontOfWeapon())
{
AimAtTarget();
}
else if (ReadyToFire())
{
//attacking = true;
UseWeapon();
}
//if (TargetInRange() && (attacking = true))
//{
// AdjustPosition();
//}
}
private bool TargetInFrontOfWeapon()
{
Vector3 targetLocation = target.transform.position;
Vector3 direction = targetLocation - transform.position;
if (direction.normalized == transform.forward.normalized) return true;
else return false;
}
private bool ReadyToFire()
{
if (currentWeaponChargeTime >= weaponRechargeTime)
{
return true;
}
return false;
}
protected virtual void UseWeapon()
{
if (audioElement != null && Time.timeScale > 0) audioElement.Play(useWeaponSound);
currentWeaponChargeTime = 0.0f;
//this behaviour needs to be specified by a specific object
}
public void TakeDamage(float damage)
{
//GameObject.Instantiate(impactVisual, target.transform.position, Quaternion.identity);
hitPoints -= damage;
if (hitPoints <= 0)
{
Instantiate(explosionPrefab, transform.position + new Vector3(0, 5, 0), Quaternion.identity);
Instantiate(splat, transform.position, Quaternion.identity);
Destroy(gameObject);
}
}
}
using UnityEngine;
using System.Collections.Generic;
namespace RTS
{
public static class WorkManager
{
public static Rect CalculateSelectionBox(Bounds selectionBounds, Rect playingArea)
{
//shorthand for the coordinates of the centre of the selection bounds
float cx = selectionBounds.center.x;
float cy = selectionBounds.center.y;
float cz = selectionBounds.center.z;
//shorthand for the coordinates of the extents of the selection bounds
float ex = selectionBounds.extents.x;
float ey = selectionBounds.extents.y;
float ez = selectionBounds.extents.z;
//Determine the screen coordinates for the corners of the selection bounds
List<Vector3> corners = new List<Vector3>();
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx + ex, cy + ey, cz + ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx + ex, cy + ey, cz - ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx + ex, cy - ey, cz + ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx - ex, cy + ey, cz + ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx + ex, cy - ey, cz - ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx - ex, cy - ey, cz + ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx - ex, cy + ey, cz - ez)));
corners.Add(Camera.main.WorldToScreenPoint(new Vector3(cx - ex, cy - ey, cz - ez)));
//Determine the bounds on screen for the selection bounds
Bounds screenBounds = new Bounds(corners[0], Vector3.zero);
for (int i = 1; i < corners.Count; i++)
{
screenBounds.Encapsulate(corners[i]);
}
//Screen coordinates start in the bottom left corner, rather than the top left corner
//this correction is needed to make sure the selection box is drawn in the correct place
float selectBoxTop = playingArea.height - (screenBounds.center.y + screenBounds.extents.y);
float selectBoxLeft = screenBounds.center.x - screenBounds.extents.x;
float selectBoxWidth = 2 * screenBounds.extents.x;
float selectBoxHeight = 2 * screenBounds.extents.y;
return new Rect(selectBoxLeft, selectBoxTop, selectBoxWidth, selectBoxHeight);
}
public static GameObject FindHitObject(Vector3 origin)
{
Ray ray = Camera.main.ScreenPointToRay(origin);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, ResourceManager.RayCastLimit)) return hit.collider.gameObject;
return null;
}
public static Vector3 FindHitPoint(Vector3 origin)
{
Ray ray = Camera.main.ScreenPointToRay(origin);
RaycastHit hit;
Debug.DrawRay(ray.origin, ray.direction * ResourceManager.RayCastLimit, Color.yellow);
if (Physics.Raycast(ray, out hit, ResourceManager.RayCastLimit)) return hit.point;
return ResourceManager.InvalidPosition;
}
public static List<WorldObject> FindNearbyObjects(Vector3 position, float range)
{
Collider[] hitColliders = Physics.OverlapSphere(position, range);
HashSet<int> nearbyObjectIds = new HashSet<int>();
List<WorldObject> nearbyObjects = new List<WorldObject>();
for (int i = 0; i < hitColliders.Length; i++)
{
Transform parent = hitColliders[i].transform.parent;
if (parent)
{
WorldObject parentObject = parent.GetComponent<WorldObject>();
if (parentObject && !nearbyObjectIds.Contains(parentObject.ObjectId))
{
nearbyObjectIds.Add (parentObject.ObjectId);
nearbyObjects.Add (parentObject);
}
}
}
return nearbyObjects;
}
public static WorldObject FindNearestWorldObjectInListToPosition(List<WorldObject> objects, Vector3 position)
{
if (objects == null || objects.Count == 0) return null;
WorldObject nearestObject = objects[0];
float sqrDistanceToNearestObject = Vector3.SqrMagnitude(position - nearestObject.transform.position);
for (int i = 1; i < objects.Count; i++)
{
float sqrDistanceToObject = Vector3.SqrMagnitude(position - objects[i].transform.position);
if (sqrDistanceToObject < sqrDistanceToNearestObject)
{
sqrDistanceToNearestObject = sqrDistanceToObject;
nearestObject = objects[i];
}
}
return nearestObject;
}
}
}
The first thing you need to check is if inside
FindNearbyObjects()
The variable
hitColliders = Physics.OverlapSphere(position, range);
Changes it's size when you instantiate new buildings. In case that is not the case, it may be because you are not adding colliders to the buildings when you instantiate them.
However, I think there are better ways for you to detect buildings without using this Physics.OverlapSphere(), which may be expensive in performance. If I were you I will would give a special tag to the buildings (the original and the instantiated ones) and I will use that in my logic to detect them. So they will be potential targets in your method:
DecideWhatToDo()
Here you can read about how to tag the GameObjects:
https://docs.unity3d.com/Manual/Tags.html
Related
if dc is not null i'm using a radius from another script and it's working fine when i'm changing the radius value in the DrawCircle script the transform in RotateAroundTarget is moving smooth to the new radius.
but if dc variable is null i want to use the local radius variable for setting the radius in runtime but when changing the radius the transform is not moving to the new radius.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class RotateAroundTarget : MonoBehaviour
{
public Transform target;
public float rotatingSpeed;
public float movingSpeed;
public Vector3 axis;
public bool randomHeight;
public float setRandomHeight = 1;
public float radius;
public DrawCircle dc;
private float lastRadius;
private bool move = false;
private float t = 0.0f;
public float upperLimit, lowerLimit, delay;
private float prevHeight;
private Vector3 radiusPosition;
private void Start()
{
if (dc != null)
{
lastRadius = dc.xRadius;
}
else
{
lastRadius = radius;
}
move = true;
}
private void Update()
{
if (dc != null)
{
radiusPosition = new Vector3(target.position.x, target.position.y, dc.xRadius);
}
else
{
radiusPosition = new Vector3(target.position.x, target.position.y, radius);
}
if (move == false)
{
transform.RotateAround(target.position, axis, rotatingSpeed * Time.deltaTime);
t += Time.deltaTime;
if (t > delay)
{
prevHeight = setRandomHeight;
setRandomHeight = Random.Range(lowerLimit, upperLimit);
t = 0;
}
var tt = transform.position;
tt.y = Mathf.Lerp(prevHeight, setRandomHeight, t);
transform.position = tt;
}
if (dc != null)
{
if (lastRadius != dc.xRadius)
{
move = true;
lastRadius = dc.xRadius;
}
}
else
{
if (lastRadius != radius)
{
move = true;
lastRadius = radius;
}
}
if (move)
{
if (transform.position != radiusPosition)
{
float step = movingSpeed * Time.deltaTime;
transform.position = Vector3.MoveTowards(transform.position,
radiusPosition, step);
}
else
{
move = false;
}
}
}
}
I am trying to add a variable to a function of a class with a namespace.
I am using Game Creator and I would like to extend/override (whatever is possible) one of the class of this package which is wrapped within their namespace from a custom script, so that I do not have to mess up with the original script.
The current challenge I have is to extend the PlayerCharacter class which is inside the...
namespace GameCreator.Characters
I do fail to understand how that can be achieved and I am trying to grasp the concept because I see this use in many situations, trying to use a component/package in unity along my custom code. So the answer to this question will change my life completely :)
PlayerCharacter.cs
namespace GameCreator.Characters
{
using UnityEngine;
using GameCreator.Core;
using GameCreator.Core.Hooks;
[AddComponentMenu("Game Creator/Characters/Player Character", 100)]
public class PlayerCharacter : Character
{
public enum INPUT_TYPE
{
PointAndClick,
Directional,
FollowPointer,
SideScrollX,
SideScrollZ,
TankControl
}
public enum MOUSE_BUTTON
{
LeftClick = 0,
RightClick = 1,
MiddleClick = 2,
None = -1
}
protected const string AXIS_H = "Horizontal";
protected const string AXIS_V = "Vertical";
protected static readonly Vector3 PLANE = new Vector3(1, 0, 1);
protected const string PLAYER_ID = "player";
public static OnLoadSceneData ON_LOAD_SCENE_DATA;
// PROPERTIES: ----------------------------------------------------------------------------
public INPUT_TYPE inputType = INPUT_TYPE.Directional;
public MOUSE_BUTTON mouseButtonMove = MOUSE_BUTTON.LeftClick;
public LayerMask mouseLayerMask = ~0;
public bool invertAxis;
public KeyCode jumpKey = KeyCode.Space;
protected bool uiConstrained;
protected Camera cacheCamera;
public Vector3 direction = Vector3.zero;
public Vector3 directionVelocity = Vector3.zero;
public bool useAcceleration = true;
public float acceleration = 4f;
public float deceleration = 2f;
private bool forceDisplayTouchstick = false;
// INITIALIZERS: --------------------------------------------------------------------------
protected override void Awake()
{
if (!Application.isPlaying) return;
this.CharacterAwake();
this.initSaveData = new SaveData()
{
position = transform.position,
rotation = transform.rotation,
};
if (this.save)
{
SaveLoadManager.Instance.Initialize(
this, (int)SaveLoadManager.Priority.Normal, true
);
}
HookPlayer hookPlayer = gameObject.GetComponent<HookPlayer>();
if (hookPlayer == null) gameObject.AddComponent<HookPlayer>();
if (ON_LOAD_SCENE_DATA != null && ON_LOAD_SCENE_DATA.active)
{
transform.position = ON_LOAD_SCENE_DATA.position;
transform.rotation = ON_LOAD_SCENE_DATA.rotation;
ON_LOAD_SCENE_DATA.Consume();
}
#if UNITY_EDITOR
DatabaseGeneral general = DatabaseGeneral.Load();
if (general.forceDisplayInEditor)
{
this.forceDisplayTouchstick = general.forceDisplayInEditor;
}
#endif
}
// UPDATE: --------------------------------------------------------------------------------
protected virtual void Update()
{
if (!Application.isPlaying) return;
switch (this.inputType)
{
case INPUT_TYPE.Directional: this.UpdateInputDirectional(); break;
case INPUT_TYPE.PointAndClick: this.UpdateInputPointClick(); break;
case INPUT_TYPE.FollowPointer: this.UpdateInputFollowPointer(); break;
case INPUT_TYPE.SideScrollX: this.UpdateInputSideScroll(Vector3.right); break;
case INPUT_TYPE.SideScrollZ: this.UpdateInputSideScroll(Vector3.forward); break;
case INPUT_TYPE.TankControl: this.UpdateInputTank(); break;
}
if (this.IsControllable())
{
if (Input.GetKeyDown(this.jumpKey)) this.Jump();
}
else
{
this.direction = Vector3.zero;
this.directionVelocity = Vector3.zero;
}
this.CharacterUpdate();
}
protected virtual void UpdateInputDirectional()
{
Vector3 targetDirection = Vector3.zero;
if (!this.IsControllable()) return;
if (Application.isMobilePlatform ||
TouchStickManager.FORCE_USAGE ||
this.forceDisplayTouchstick)
{
Vector2 touchDirection = TouchStickManager.Instance.GetDirection(this);
targetDirection = new Vector3(touchDirection.x, 0.0f, touchDirection.y);
}
else
{
targetDirection = new Vector3(
Input.GetAxisRaw(AXIS_H),
0.0f,
Input.GetAxisRaw(AXIS_V)
);
}
this.ComputeMovement(targetDirection);
Camera maincam = this.GetMainCamera();
if (maincam == null) return;
Vector3 moveDirection = (
Quaternion.Euler(0, maincam.transform.rotation.eulerAngles.y, 0) *
this.direction
);
this.characterLocomotion.SetDirectionalDirection(moveDirection);
}
protected virtual void UpdateInputTank()
{
Vector3 movement = Vector3.zero;
float rotationY = 0f;
if (!this.IsControllable()) return;
if (Application.isMobilePlatform ||
TouchStickManager.FORCE_USAGE ||
this.forceDisplayTouchstick)
{
Vector2 touchDirection = TouchStickManager.Instance.GetDirection(this);
movement = new Vector3(0f, 0.0f, touchDirection.y);
rotationY = touchDirection.x;
}
else
{
movement = transform.TransformDirection(new Vector3(
0f,
0f,
Input.GetAxisRaw(AXIS_V)
));
rotationY = Input.GetAxis(AXIS_H);
}
this.ComputeMovement(movement);
this.characterLocomotion.SetTankDirection(this.direction, rotationY);
}
protected virtual void UpdateInputPointClick()
{
if (!this.IsControllable()) return;
this.UpdateUIConstraints();
if (Input.GetMouseButtonDown((int)this.mouseButtonMove) && !this.uiConstrained)
{
Camera maincam = this.GetMainCamera();
if (maincam == null) return;
Ray cameraRay = maincam.ScreenPointToRay(Input.mousePosition);
this.characterLocomotion.SetTarget(cameraRay, this.mouseLayerMask, null, 0f, null);
}
}
protected virtual void UpdateInputFollowPointer()
{
if (!this.IsControllable()) return;
this.UpdateUIConstraints();
if (Input.GetMouseButton((int)this.mouseButtonMove) && !this.uiConstrained)
{
if (HookPlayer.Instance == null) return;
Camera maincam = this.GetMainCamera();
if (maincam == null) return;
Ray cameraRay = maincam.ScreenPointToRay(Input.mousePosition);
Transform player = HookPlayer.Instance.transform;
Plane groundPlane = new Plane(Vector3.up, player.position);
float rayDistance = 0f;
if (groundPlane.Raycast(cameraRay, out rayDistance))
{
Vector3 cursor = cameraRay.GetPoint(rayDistance);
if (Vector3.Distance(player.position, cursor) >= 0.05f)
{
Vector3 target = Vector3.MoveTowards(player.position, cursor, 1f);
this.characterLocomotion.SetTarget(target, null, 0f, null);
}
}
}
}
protected virtual void UpdateInputSideScroll(Vector3 axis)
{
Vector3 targetDirection = Vector3.zero;
if (!this.IsControllable()) return;
if (Application.isMobilePlatform ||
TouchStickManager.FORCE_USAGE ||
this.forceDisplayTouchstick)
{
Vector2 touchDirection = TouchStickManager.Instance.GetDirection(this);
targetDirection = axis * touchDirection.x;
}
else
{
targetDirection = axis * Input.GetAxis(AXIS_H);
}
Camera maincam = this.GetMainCamera();
if (maincam == null) return;
this.ComputeMovement(targetDirection);
float invertValue = (this.invertAxis ? -1 : 1);
Vector3 moveDirection = Vector3.Scale(this.direction, axis * invertValue);
moveDirection.Normalize();
moveDirection *= this.direction.magnitude;
this.characterLocomotion.SetDirectionalDirection(moveDirection);
}
// OTHER METHODS: -------------------------------------------------------------------------
protected Camera GetMainCamera()
{
if (HookCamera.Instance != null) return HookCamera.Instance.Get<Camera>();
if (this.cacheCamera != null) return this.cacheCamera;
this.cacheCamera = Camera.main;
if (this.cacheCamera != null)
{
return this.cacheCamera;
}
this.cacheCamera = GameObject.FindObjectOfType<Camera>();
if (this.cacheCamera != null)
{
return this.cacheCamera;
}
Debug.LogError(ERR_NOCAM, gameObject);
return null;
}
protected void UpdateUIConstraints()
{
EventSystemManager.Instance.Wakeup();
this.uiConstrained = EventSystemManager.Instance.IsPointerOverUI();
#if UNITY_IOS || UNITY_ANDROID
for (int i = 0; i < Input.touches.Length; ++i)
{
if (Input.GetTouch(i).phase != TouchPhase.Began) continue;
int fingerID = Input.GetTouch(i).fingerId;
bool pointerOverUI = EventSystemManager.Instance.IsPointerOverUI(fingerID);
if (pointerOverUI) this.uiConstrained = true;
}
#endif
}
protected void ComputeMovement(Vector3 target)
{
switch (this.useAcceleration)
{
case true:
float acceleration = Mathf.Approximately(target.sqrMagnitude, 0f)
? this.deceleration
: this.acceleration;
this.direction = Vector3.SmoothDamp(
this.direction, target,
ref this.directionVelocity,
1f / acceleration,
acceleration
);
if (Mathf.Abs(target.sqrMagnitude) < 0.05f &&
Mathf.Abs(this.direction.sqrMagnitude) < 0.05f)
{
this.direction = Vector3.zero;
}
break;
case false:
this.direction = target;
break;
}
}
// PUBLIC METHODS: ------------------------------------------------------------------------
public void ForceDirection(Vector3 forceDirection)
{
this.direction = forceDirection;
this.directionVelocity = Vector3.zero;
}
// GAME SAVE: -----------------------------------------------------------------------------
protected override string GetUniqueCharacterID()
{
return PLAYER_ID;
}
}
}
And My custom Script Located in another folder outside the game creator folder.
The Paths are:
Assets\Plugins\GameCreator\Characters\Mono\Characters\PlayerCharacter.cs
Assets\Custom\PlayerInputExt.cs
What I want to start with is just to get started by replicate the INPUT_TYPE Directional with a different name:
PlayerInputExt.cs
using UnityEngine;
using System.Collections;
public class PlayerInputExt
{
public enum INPUT_TYPE
{
// Want to add this Variable and make it functional based on the original script
NewInputSystem
}
// PROPERTIES: ----------------------------------------------------------------------------
public INPUT_TYPE inputType = INPUT_TYPE.NewInputSystem;
// UPDATE: --------------------------------------------------------------------------------
protected virtual void Update()
{
if (!Application.isPlaying) return;
switch (this.inputType)
{
case INPUT_TYPE.NewInputSystem: this.UpdateInputNewInputSystem(); break;
}
}
// Functions: --------------------------------------------------------------------------------
protected virtual void UpdateInputNewInputSystem()
{
Vector3 targetDirection = Vector3.zero;
if (!this.IsControllable()) return;
if (Application.isMobilePlatform ||
TouchStickManager.FORCE_USAGE ||
this.forceDisplayTouchstick)
{
Vector2 touchDirection = TouchStickManager.Instance.GetDirection(this);
targetDirection = new Vector3(touchDirection.x, 0.0f, touchDirection.y);
}
else
{
targetDirection = new Vector3(
Input.GetAxisRaw(AXIS_H),
0.0f,
Input.GetAxisRaw(AXIS_V)
);
}
this.ComputeMovement(targetDirection);
Camera maincam = this.GetMainCamera();
if (maincam == null) return;
Vector3 moveDirection = (
Quaternion.Euler(0, maincam.transform.rotation.eulerAngles.y, 0) *
this.direction
);
this.characterLocomotion.SetDirectionalDirection(moveDirection);
}
}
I hope someone can make a clear and good explanation regarding this situation and possibly similar situations with more ways to achieve the results but to start with a direct example I am confident I would finally start to understand how it works.
Thank you in advance!
The class you want to extend is not sealed, which means you can just inherit from it. You can your own script to a an existing namespace, this is not forbidden as long as you are not using colliding names, but maybe just adding "using GameCreator.Characters" at the top would do the trick?
namespace GameCreator.Characters
{
using UnityEngine;
using GameCreator.Core;
using GameCreator.Core.Hooks;
public class PlayerInputExt: PlayerCharacter
{
// use overrides to change behavious
protected override void Update()
{
// add your own code to override existing virtual method
}
}
}
As for extending the enum, this is not possible, but you could bypass it using a bool value (for example useNewInput), but in your case it seems this wouldn't even be necessary, unless you want to keep existing functinality just in case
Very new to Unity, I'm making a tactical RPG game similar to Fire Emblem. I've followed a tutorial on movement from this website and followed everything he did.
The player character can only move 5 tiles in the directions +z, -z, +x, -x on a 12x12 tile grid, however I want it to move 6. In the TacticsMove.cs script, there is this variable: public int move = 5; with the amount of the variable being how many tiles the player moves. I've changed the variable to public int move = 6; and saved the script, but everything is the exact same as before.
I want public int move = 6 to allow the player to move up to 6 tiles instead of 5. There are no comments on the tutorial or youtube videos of this happening so the next place im coming to is here. My code is below, I don't know if all of this is relevant. If you need me to add/remove something, tell me.
TacticsMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TacticsMove : MonoBehaviour
{
public bool turn = false;
List<Tile> selectableTiles = new List<Tile>();
GameObject[] tiles;
Stack<Tile> path = new Stack<Tile>();
Tile currentTile;
public bool moving = false;
public int move = 6;
public float jumpHeight = 2;
public float moveSpeed = 2;
public float jumpVelocity = 4.5f;
Vector3 velocity = new Vector3();
Vector3 heading = new Vector3();
float halfHeight = 0;
bool fallingDown = false;
bool jumpingUp = false;
bool movingEdge = false;
Vector3 jumpTarget;
public Tile actualTargetTile;
protected void Init()
{
tiles = GameObject.FindGameObjectsWithTag("Tile");
halfHeight = GetComponent<Collider>().bounds.extents.y;
TurnManager.AddUnit(this);
}
public void GetCurrentTile()
{
currentTile = GetTargetTile(gameObject);
currentTile.current = true;
}
public Tile GetTargetTile(GameObject target)
{
RaycastHit hit;
Tile tile = null;
if (Physics.Raycast(target.transform.position, -Vector3.up, out hit, 1))
{
tile = hit.collider.GetComponent<Tile>();
}
return tile;
}
public void ComputeAdjacencyLists(float jumpHeight, Tile target)
{
//tiles = GameObject.FindGameObjectsWithTag("Tile");
foreach (GameObject tile in tiles)
{
Tile t = tile.GetComponent<Tile>();
t.FindNeighbors(jumpHeight, target);
}
}
public void FindSelectableTiles()
{
ComputeAdjacencyLists(jumpHeight, null);
GetCurrentTile();
Queue<Tile> process = new Queue<Tile>();
process.Enqueue(currentTile);
currentTile.visited = true;
//currentTile.parent = ?? leave as null
while (process.Count > 0)
{
Tile t = process.Dequeue();
selectableTiles.Add(t);
t.selectable = true;
if (t.distance < move)
{
foreach (Tile tile in t.adjacencyList)
{
if (!tile.visited)
{
tile.parent = t;
tile.visited = true;
tile.distance = 1 + t.distance;
process.Enqueue(tile);
}
}
}
}
}
public void MoveToTile(Tile tile)
{
path.Clear();
tile.target = true;
moving = true;
Tile next = tile;
while (next != null)
{
path.Push(next);
next = next.parent;
}
}
public void Move()
{
if (path.Count > 0)
{
Tile t = path.Peek();
Vector3 target = t.transform.position;
//Calculate the unit's position on top of the target tile
target.y += halfHeight + t.GetComponent<Collider>().bounds.extents.y;
if (Vector3.Distance(transform.position, target) >= 0.05f)
{
bool jump = transform.position.y != target.y;
if (jump)
{
Jump(target);
}
else
{
CalculateHeading(target);
SetHorizotalVelocity();
}
//Locomotion
transform.forward = heading;
transform.position += velocity * Time.deltaTime;
}
else
{
//Tile center reached
transform.position = target;
path.Pop();
}
}
else
{
RemoveSelectableTiles();
moving = false;
TurnManager.EndTurn();
}
}
protected void RemoveSelectableTiles()
{
if (currentTile != null)
{
currentTile.current = false;
currentTile = null;
}
foreach (Tile tile in selectableTiles)
{
tile.Reset();
}
selectableTiles.Clear();
}
void CalculateHeading(Vector3 target)
{
heading = target - transform.position;
heading.Normalize();
}
void SetHorizotalVelocity()
{
velocity = heading * moveSpeed;
}
void Jump(Vector3 target)
{
if (fallingDown)
{
FallDownward(target);
}
else if (jumpingUp)
{
JumpUpward(target);
}
else if (movingEdge)
{
MoveToEdge();
}
else
{
PrepareJump(target);
}
}
void PrepareJump(Vector3 target)
{
float targetY = target.y;
target.y = transform.position.y;
CalculateHeading(target);
if (transform.position.y > targetY)
{
fallingDown = false;
jumpingUp = false;
movingEdge = true;
jumpTarget = transform.position + (target - transform.position) / 2.0f;
}
else
{
fallingDown = false;
jumpingUp = true;
movingEdge = false;
velocity = heading * moveSpeed / 3.0f;
float difference = targetY - transform.position.y;
velocity.y = jumpVelocity * (0.5f + difference / 2.0f);
}
}
void FallDownward(Vector3 target)
{
velocity += Physics.gravity * Time.deltaTime;
if (transform.position.y <= target.y)
{
fallingDown = false;
jumpingUp = false;
movingEdge = false;
Vector3 p = transform.position;
p.y = target.y;
transform.position = p;
velocity = new Vector3();
}
}
void JumpUpward(Vector3 target)
{
velocity += Physics.gravity * Time.deltaTime;
if (transform.position.y > target.y)
{
jumpingUp = false;
fallingDown = true;
}
}
void MoveToEdge()
{
if (Vector3.Distance(transform.position, jumpTarget) >= 0.05f)
{
SetHorizotalVelocity();
}
else
{
movingEdge = false;
fallingDown = true;
velocity /= 5.0f;
velocity.y = 1.5f;
}
}
protected Tile FindLowestF(List<Tile> list)
{
Tile lowest = list[0];
foreach (Tile t in list)
{
if (t.f < lowest.f)
{
lowest = t;
}
}
list.Remove(lowest);
return lowest;
}
protected Tile FindEndTile(Tile t)
{
Stack<Tile> tempPath = new Stack<Tile>();
Tile next = t.parent;
while (next != null)
{
tempPath.Push(next);
next = next.parent;
}
if (tempPath.Count <= move)
{
return t.parent;
}
Tile endTile = null;
for (int i = 0; i <= move; i++)
{
endTile = tempPath.Pop();
}
return endTile;
}
protected void FindPath(Tile target)
{
ComputeAdjacencyLists(jumpHeight, target);
GetCurrentTile();
List<Tile> openList = new List<Tile>();
List<Tile> closedList = new List<Tile>();
openList.Add(currentTile);
//currentTile.parent = ??
currentTile.h = Vector3.Distance(currentTile.transform.position, target.transform.position);
currentTile.f = currentTile.h;
while (openList.Count > 0)
{
Tile t = FindLowestF(openList);
closedList.Add(t);
if (t == target)
{
actualTargetTile = FindEndTile(t);
MoveToTile(actualTargetTile);
return;
}
foreach (Tile tile in t.adjacencyList)
{
if (closedList.Contains(tile))
{
//Do nothing, already processed
}
else if (openList.Contains(tile))
{
float tempG = t.g + Vector3.Distance(tile.transform.position, t.transform.position);
if (tempG < tile.g)
{
tile.parent = t;
tile.g = tempG;
tile.f = tile.g + tile.h;
}
}
else
{
tile.parent = t;
tile.g = t.g + Vector3.Distance(tile.transform.position, t.transform.position);
tile.h = Vector3.Distance(tile.transform.position, target.transform.position);
tile.f = tile.g + tile.h;
openList.Add(tile);
}
}
}
//todo - what do you do if there is no path to the target tile?
Debug.Log("Path not found");
}
public void BeginTurn()
{
turn = true;
}
public void EndTurn()
{
turn = false;
}
}
Tile.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tile : MonoBehaviour
{
public bool walkable = true;
public bool current = false;
public bool target = false;
public bool selectable = false;
public List<Tile> adjacencyList = new List<Tile>();
//Needed BFS (breadth first search)
public bool visited = false;
public Tile parent = null;
public int distance = 0;
//For A*
public float f = 0;
public float g = 0;
public float h = 0;
// Use this for initialization
void Start ()
{
}
// Update is called once per frame
void Update ()
{
if (current)
{
GetComponent<Renderer>().material.color = Color.magenta;
}
else if (target)
{
GetComponent<Renderer>().material.color = Color.green;
}
else if (selectable)
{
GetComponent<Renderer>().material.color = Color.blue;
}
else
{
GetComponent<Renderer>().material.color = Color.white;
}
}
public void Reset()
{
adjacencyList.Clear();
current = false;
target = false;
selectable = false;
visited = false;
parent = null;
distance = 0;
f = g = h = 0;
}
public void FindNeighbors(float jumpHeight, Tile target)
{
Reset();
CheckTile(Vector3.forward, jumpHeight, target);
CheckTile(-Vector3.forward, jumpHeight, target);
CheckTile(Vector3.right, jumpHeight, target);
CheckTile(-Vector3.right, jumpHeight, target);
}
public void CheckTile(Vector3 direction, float jumpHeight, Tile target)
{
Vector3 halfExtents = new Vector3(0.25f, (1 + jumpHeight) / 2.0f, 0.25f);
Collider[] colliders = Physics.OverlapBox(transform.position + direction, halfExtents);
foreach (Collider item in colliders)
{
Tile tile = item.GetComponent<Tile>();
if (tile != null && tile.walkable)
{
RaycastHit hit;
if (!Physics.Raycast(tile.transform.position, Vector3.up, out hit, 1) || (tile == target))
{
adjacencyList.Add(tile);
}
}
}
}
}
PlayerMove.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerMove : TacticsMove
{
// Use this for initialization
void Start ()
{
Init();
}
// Update is called once per frame
void Update ()
{
Debug.DrawRay(transform.position, transform.forward);
if (!turn)
{
return;
}
if (!moving)
{
FindSelectableTiles();
CheckMouse();
}
else
{
Move();
}
}
void CheckMouse()
{
if (Input.GetMouseButtonUp(0))
{
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit))
{
if (hit.collider.tag == "Tile")
{
Tile t = hit.collider.GetComponent<Tile>();
if (t.selectable)
{
MoveToTile(t);
}
}
}
}
}
}
Im using unity version 2019.3.12f1.
Any help is appreciated.
As Etienne de Martel hints, Unity saves your public variables in the scene along with all the other GameObject/Component data, and restores that data on load
Field initializers are the default values for new components, they do not set the values for existing components even with a recompile.
I've been through this a few times myself.
From what I know, variables that have been serialized (which means it is visible in the inspector using [serialize] or it is set to public) will always overwrite scripts. This means that the moment u save ur script after u have create a variable and before u start the program, it can only be adjusted using the inspector
I am developing for the HTC VIVE and am trying to create a teleportation script that would allow the user to teleport to a certain location (predefined by me) when the user grabs a certain object. I currently have a teleportation code that works like a normal teleporter where the user points at a location and the room is moved to that location. I have modified this so that no matter where the user is pointing they will always teleport to the specific location. This is a first step but I am really looking to trigger this teleportation when the user picks up a certain object, does anyone have any ideas on where to star or how to do this?
Here is the code for the modified teleporter:
namespace VRTK{
using UnityEngine;
using System.Collections;
public delegate void TeleportEventHandler(object sender, DestinationMarkerEventArgs e);
public class VRTK_BasicTeleport : MonoBehaviour
{
public float blinkTransitionSpeed = 0.6f;
[Range(0f, 32f)]
public float distanceBlinkDelay = 0f;
public bool headsetPositionCompensation = true;
public string ignoreTargetWithTagOrClass;
public bool limitToNavMesh = false;
public event TeleportEventHandler Teleporting;
public event TeleportEventHandler Teleported;
protected Transform eyeCamera;
protected bool adjustYForTerrain = false;
protected bool enableTeleport = true;
private float blinkPause = 0f;
private float fadeInTime = 0f;
private float maxBlinkTransitionSpeed = 1.5f;
private float maxBlinkDistance = 33f;
public void InitDestinationSetListener(GameObject markerMaker)
{
if (markerMaker)
{
foreach (var worldMarker in markerMaker.GetComponents<VRTK_DestinationMarker>())
{
worldMarker.DestinationMarkerSet += new DestinationMarkerEventHandler(DoTeleport);
worldMarker.SetInvalidTarget(ignoreTargetWithTagOrClass);
worldMarker.SetNavMeshCheck(limitToNavMesh);
worldMarker.SetHeadsetPositionCompensation(headsetPositionCompensation);
}
}
}
protected virtual void Start()
{
Utilities.SetPlayerObject(this.gameObject, VRTK_PlayerObject.ObjectTypes.CameraRig);
adjustYForTerrain = false;
eyeCamera = Utilities.AddCameraFade();
InitDestinationMarkerListeners();
InitHeadsetCollisionListener();
enableTeleport = true;
}
protected void OnTeleporting(object sender, DestinationMarkerEventArgs e)
{
if (Teleporting != null)
Teleporting(this, e);
}
protected void OnTeleported(object sender, DestinationMarkerEventArgs e)
{
if (Teleported != null)
Teleported(this, e);
}
protected virtual void Blink(float transitionSpeed)
{
fadeInTime = transitionSpeed;
SteamVR_Fade.Start(Color.black, 0);
Invoke("ReleaseBlink", blinkPause);
}
protected virtual bool ValidLocation(Transform target)
{
//If the target is one of the player objects or a UI Canvas then it's never a valid location
if(target.GetComponent<VRTK_PlayerObject>() || target.GetComponent<VRTK_UIGraphicRaycaster>())
{
return false;
}
bool validNavMeshLocation = false;
if (target)
{
NavMeshHit hit;
validNavMeshLocation = NavMesh.SamplePosition(target.position, out hit, 1.0f, NavMesh.AllAreas);
}
if (!limitToNavMesh)
{
validNavMeshLocation = true;
}
return (validNavMeshLocation && target && target.tag != ignoreTargetWithTagOrClass && target.GetComponent(ignoreTargetWithTagOrClass) == null);
}
protected virtual void DoTeleport(object sender, DestinationMarkerEventArgs e)
{
if (enableTeleport && ValidLocation(e.target) && e.enableTeleport)
{
OnTeleporting(sender, e);
Vector3 newPosition = GetNewPosition(e.destinationPosition, e.target);
CalculateBlinkDelay(blinkTransitionSpeed, newPosition);
Blink(blinkTransitionSpeed);
SetNewPosition(newPosition, e.target);
OnTeleported(sender, e);
}
}
protected virtual void SetNewPosition(Vector3 position, Transform target)
{
this.transform.position = CheckTerrainCollision(position, target);
}
protected virtual Vector3 GetNewPosition(Vector3 tipPosition, Transform target)
{
float newX = 0;
float newY = 17;
float newZ = 0;
return new Vector3(newX, newY, newZ);
}
protected Vector3 CheckTerrainCollision(Vector3 position, Transform target)
{
if (adjustYForTerrain && target.GetComponent<Terrain>())
{
var terrainHeight = Terrain.activeTerrain.SampleHeight(position);
position.y = (terrainHeight > position.y ? position.y : terrainHeight);
}
return position;
}
private void CalculateBlinkDelay(float blinkSpeed, Vector3 newPosition)
{
blinkPause = 0f;
if (distanceBlinkDelay > 0f)
{
float distance = Vector3.Distance(this.transform.position, newPosition);
blinkPause = Mathf.Clamp((distance * blinkTransitionSpeed) / (maxBlinkDistance - distanceBlinkDelay), 0, maxBlinkTransitionSpeed);
blinkPause = (blinkSpeed <= 0.25 ? 0f : blinkPause);
}
}
private void ReleaseBlink()
{
SteamVR_Fade.Start(Color.clear, fadeInTime);
fadeInTime = 0f;
}
private void InitDestinationMarkerListeners()
{
var controllerManager = GameObject.FindObjectOfType<SteamVR_ControllerManager>();
InitDestinationSetListener(controllerManager.left);
InitDestinationSetListener(controllerManager.right);
foreach (var destinationMarker in GameObject.FindObjectsOfType<VRTK_DestinationMarker>())
{
if (destinationMarker.gameObject != controllerManager.left && destinationMarker.gameObject != controllerManager.right)
{
InitDestinationSetListener(destinationMarker.gameObject);
}
}
}
private void InitHeadsetCollisionListener()
{
var headset = GameObject.FindObjectOfType<VRTK_HeadsetCollisionFade>();
if (headset)
{
headset.HeadsetCollisionDetect += new HeadsetCollisionEventHandler(DisableTeleport);
headset.HeadsetCollisionEnded += new HeadsetCollisionEventHandler(EnableTeleport);
}
}
private void DisableTeleport(object sender, HeadsetCollisionEventArgs e)
{
enableTeleport = false;
}
private void EnableTeleport(object sender, HeadsetCollisionEventArgs e)
{
enableTeleport = true;
}
}
And here is the code for the pointer:
namespace VRTK{
using UnityEngine;
using System.Collections;
public class VRTK_BezierPointer : VRTK_WorldPointer
{
public float pointerLength = 10f;
public int pointerDensity = 10;
public bool showPointerCursor = true;
public float pointerCursorRadius = 0.5f;
public float beamCurveOffset = 1f;
public GameObject customPointerTracer;
public GameObject customPointerCursor;
public LayerMask layersToIgnore = Physics.IgnoreRaycastLayer;
private GameObject projectedBeamContainer;
private GameObject projectedBeamForward;
private GameObject projectedBeamJoint;
private GameObject projectedBeamDown;
private GameObject pointerCursor;
private GameObject curvedBeamContainer;
private CurveGenerator curvedBeam;
// Use this for initialization
protected override void Start()
{
base.Start();
InitProjectedBeams();
InitPointer();
TogglePointer(false);
}
protected override void Update()
{
base.Update();
if (projectedBeamForward.gameObject.activeSelf)
{
ProjectForwardBeam();
ProjectDownBeam();
DisplayCurvedBeam();
SetPointerCursor();
}
}
protected override void InitPointer()
{
pointerCursor = (customPointerCursor ? Instantiate(customPointerCursor) : CreateCursor());
pointerCursor.name = string.Format("[{0}]WorldPointer_BezierPointer_PointerCursor", this.gameObject.name);
Utilities.SetPlayerObject(pointerCursor, VRTK_PlayerObject.ObjectTypes.Pointer);
pointerCursor.layer = LayerMask.NameToLayer("Ignore Raycast");
pointerCursor.SetActive(false);
curvedBeamContainer = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_CurvedBeamContainer", this.gameObject.name));
Utilities.SetPlayerObject(curvedBeamContainer, VRTK_PlayerObject.ObjectTypes.Pointer);
curvedBeamContainer.SetActive(false);
curvedBeam = curvedBeamContainer.gameObject.AddComponent<CurveGenerator>();
curvedBeam.transform.parent = null;
curvedBeam.Create(pointerDensity, pointerCursorRadius, customPointerTracer);
base.InitPointer();
}
protected override void SetPointerMaterial()
{
if (pointerCursor.GetComponent<Renderer>())
{
pointerCursor.GetComponent<Renderer>().material = pointerMaterial;
}
foreach (Renderer mr in pointerCursor.GetComponentsInChildren<Renderer>())
{
mr.material = pointerMaterial;
}
base.SetPointerMaterial();
}
protected override void TogglePointer(bool state)
{
state = (pointerVisibility == pointerVisibilityStates.Always_On ? true : state);
projectedBeamForward.gameObject.SetActive(state);
projectedBeamJoint.gameObject.SetActive(state);
projectedBeamDown.SetActive(state);
}
protected override void DisablePointerBeam(object sender, ControllerInteractionEventArgs e)
{
base.DisablePointerBeam(sender, e);
TogglePointerCursor(false);
curvedBeam.TogglePoints(false);
}
protected override void OnDestroy()
{
base.OnDestroy();
if (projectedBeamDown != null)
{
Destroy(projectedBeamDown);
}
if (pointerCursor != null)
{
Destroy(pointerCursor);
}
if (curvedBeam != null)
{
Destroy(curvedBeam);
}
if (projectedBeamContainer != null)
{
Destroy(projectedBeamContainer);
}
if (curvedBeamContainer != null)
{
Destroy(curvedBeamContainer);
}
}
private GameObject CreateCursor()
{
var cursorYOffset = 0.02f;
var cursor = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
cursor.GetComponent<MeshRenderer>().shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
cursor.GetComponent<MeshRenderer>().receiveShadows = false;
cursor.transform.localScale = new Vector3(pointerCursorRadius, cursorYOffset, pointerCursorRadius);
Destroy(cursor.GetComponent<CapsuleCollider>());
return cursor;
}
private void TogglePointerCursor(bool state)
{
var pointerCursorState = (showPointerCursor && state ? showPointerCursor : false);
var playAreaCursorState = (showPlayAreaCursor && state ? showPlayAreaCursor : false);
pointerCursor.gameObject.SetActive(pointerCursorState);
base.TogglePointer(playAreaCursorState);
}
private void InitProjectedBeams()
{
projectedBeamContainer = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamContainer", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamContainer, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamContainer.transform.parent = this.transform;
projectedBeamContainer.transform.localPosition = Vector3.zero;
projectedBeamForward = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamForward", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamForward, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamForward.transform.parent = projectedBeamContainer.transform;
projectedBeamJoint = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamJoint", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamJoint, VRTK_PlayerObject.ObjectTypes.Pointer);
projectedBeamJoint.transform.parent = projectedBeamContainer.transform;
projectedBeamJoint.transform.localScale = new Vector3(0.01f, 0.01f, 0.01f);
projectedBeamDown = new GameObject(string.Format("[{0}]WorldPointer_BezierPointer_ProjectedBeamDown", this.gameObject.name));
Utilities.SetPlayerObject(projectedBeamDown, VRTK_PlayerObject.ObjectTypes.Pointer);
}
private float GetForwardBeamLength()
{
var actualLength = pointerLength;
Ray pointerRaycast = new Ray(transform.position, transform.forward);
RaycastHit collidedWith;
var hasRayHit = Physics.Raycast(pointerRaycast, out collidedWith, pointerLength, ~layersToIgnore);
//reset if beam not hitting or hitting new target
if (!hasRayHit || (pointerContactTarget && pointerContactTarget != collidedWith.transform))
{
pointerContactDistance = 0f;
}
//check if beam has hit a new target
if (hasRayHit)
{
pointerContactDistance = collidedWith.distance;
}
//adjust beam length if something is blocking it
if (hasRayHit && pointerContactDistance < pointerLength)
{
actualLength = pointerContactDistance;
}
return actualLength;
}
private void ProjectForwardBeam()
{
var setThicknes = 0.01f;
var setLength = GetForwardBeamLength();
//if the additional decimal isn't added then the beam position glitches
var beamPosition = setLength / (2 + 0.00001f);
projectedBeamForward.transform.localScale = new Vector3(setThicknes, setThicknes, setLength);
projectedBeamForward.transform.localPosition = new Vector3(0f, 0f, beamPosition);
projectedBeamJoint.transform.localPosition = new Vector3(0f, 0f, setLength - (projectedBeamJoint.transform.localScale.z / 2));
projectedBeamContainer.transform.localRotation = Quaternion.identity;
}
private void ProjectDownBeam()
{
projectedBeamDown.transform.position = new Vector3(projectedBeamJoint.transform.position.x, projectedBeamJoint.transform.position.y, projectedBeamJoint.transform.position.z);
Ray projectedBeamDownRaycast = new Ray(projectedBeamDown.transform.position, Vector3.down);
RaycastHit collidedWith;
var downRayHit = Physics.Raycast(projectedBeamDownRaycast, out collidedWith, float.PositiveInfinity, ~layersToIgnore);
if (!downRayHit || (pointerContactTarget && pointerContactTarget != collidedWith.transform))
{
if (pointerContactTarget != null)
{
base.PointerOut();
}
pointerContactTarget = null;
destinationPosition = Vector3.zero;
}
if (downRayHit)
{
projectedBeamDown.transform.position = new Vector3(projectedBeamJoint.transform.position.x, projectedBeamJoint.transform.position.y - collidedWith.distance, projectedBeamJoint.transform.position.z);
projectedBeamDown.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);
pointerContactTarget = collidedWith.transform;
destinationPosition = projectedBeamDown.transform.position;
base.PointerIn();
}
}
private void SetPointerCursor()
{
if (pointerContactTarget != null)
{
TogglePointerCursor(true);
pointerCursor.transform.position = projectedBeamDown.transform.position;
base.SetPlayAreaCursorTransform(pointerCursor.transform.position);
UpdatePointerMaterial(pointerHitColor);
}
else
{
TogglePointerCursor(false);
UpdatePointerMaterial(pointerMissColor);
}
}
private void DisplayCurvedBeam()
{
Vector3[] beamPoints = new Vector3[]
{
this.transform.position,
projectedBeamJoint.transform.position + new Vector3(0f, beamCurveOffset, 0f),
projectedBeamDown.transform.position,
projectedBeamDown.transform.position,
};
curvedBeam.SetPoints(beamPoints, pointerMaterial);
if (pointerVisibility != pointerVisibilityStates.Always_Off)
{
curvedBeam.TogglePoints(true);
}
}
}
}
How are you trying to pick the object. Do you use some sort of ray cast or just pick up on collision ? Nevertheless whatever you want to do triggering the teleportation when the object is picked up should be as simple as calling the teleport script from whatever script you using to pick up the object.
for eg:
void OnTriggerEnter(Collider other)
{
if (other.gameObject.CompareTag ("Pick Up"))
{
<<call your teleport script here>>
}
}
Unity has really nice documentation for scripting and you can find a lot of tutorials that explain the basics, even if you go through one of them you should be able to do mostly anything you want with relative ease.
I'm making a game in Unity3D with C#. I am using GUI.box to show a healthbar for the mobs, but I only want to show the GUI.box if there is a target.
This is my code at the moment.
public GameObject target;
public bool existsTarget;
// Use this for initialization
void Start()
{
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;
existsTarget = false;
}
// Update is called once per frame
void Update()
{
if(target != null)
existsTarget = true;
else
existsTarget = false;
}
void OnGUI()
{
if(existsTarget)
GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
else {
GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
}
Unfortunately this doesn't show any healthbars at all. Any ideas as to why?
Posting the scripts here after popular demand.
public class Targetting : MonoBehaviour {
public List<Transform> targets;
public List<Transform> items;
public GameObject TheSelectedTarget {get; set;}
private Transform selectedTarget;
private Transform selectedItem;
private Transform myTransform;
// Use this for initialization
void Start () {
targets = new List<Transform>();
items = new List<Transform>();
selectedTarget = null;
selectedItem = null;
myTransform = transform;
TheSelectedTarget = null;
addAllEnemies();
addAllItems();
}
//adds all targets to a list
private void addAllEnemies() {
GameObject[] go = GameObject.FindGameObjectsWithTag("Enemy");
foreach(GameObject enemy in go){
addTarget(enemy.transform);
}
}
//adds a target
private void addTarget(Transform enemy) {
targets.Add(enemy);
}
//sorts target by distance
private void sortTargets() {
targets.Sort(delegate(Transform t1, Transform t2) {
return Vector3.Distance(t1.position, myTransform.position).CompareTo(Vector3.Distance(t2.position, myTransform.position));
});
}
//targets an enemy
private void targetEnemy() {
addAllEnemies();
if(selectedTarget == null) {
sortTargets();
selectedTarget = targets[0];
} else {
int index = targets.IndexOf(selectedTarget);
if(index < targets.Count -1) {
index++;
} else {
index = 0;
}
deselectTarget();
selectedTarget = targets[index];
}
selectTarget();
targets.Clear();
}
//selects a specific target, and colors it red
public void selectTarget() {
selectedTarget.renderer.material.color = Color.red;
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
pa.target = selectedTarget.gameObject;
TheSelectedTarget = pa.target;
}
//deselects the current selected target, and colors i grey
private void deselectTarget() {
selectedTarget.renderer.material.color = Color.gray;
selectedTarget = null;
}
//adds all items to a list
void addAllItems() {
GameObject[] go = GameObject.FindGameObjectsWithTag("Book");
foreach(GameObject book in go){
addItem(book.transform);
}
}
'
.... And then the script continues but without any relevance to this...
' public class EnemyHealth : MonoBehaviour
{
public string enemyName;
public int maxHealth = 100;
public int curHealth = 100;
public float healthBarLength;
public GameObject target;
public bool existsTarget;
public AudioSource dying;
// Use this for initialization
void Start()
{
//enemyName = this.enemyName;
healthBarLength = Screen.width / 3;
existsTarget = false;
}
// Update is called once per frame
void Update()
{
adjustCurHealth(0);
Targetting ta = (Targetting)GetComponent("Targetting");
target = ta.TheSelectedTarget;
Debug.Log (target);
if(target != null)
existsTarget = true;
else {
existsTarget = false;
}
}
void OnGUI()
{
if(existsTarget)
GUI.Box(new Rect(500, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
else {
GUI.Box(new Rect(Screen.width, 10, healthBarLength, 20), curHealth + "/" + maxHealth);
}
}
public void adjustCurHealth(int adj)
{
curHealth += adj;
if (curHealth < 0)
curHealth = 0;
if (curHealth > 100)
curHealth = 100;
if (maxHealth < 0)
maxHealth = 1;
if(curHealth == 0)
{
//dying.Play ();
GameObject.Destroy(gameObject);
}
healthBarLength = (Screen.width / 3) * (curHealth / (float)maxHealth);
}
}
Are you ever setting the target anywhere other than the Start() method? The code you show will only ever show a GUI.box if the PlayerAttack.Target is not null at the start. Try moving this code to the Update() method.
PlayerAttack pa = (PlayerAttack)GetComponent("PlayerAttack");
target = pa.target;
Edit:
Check to see if the target is null, that could be the issue.
target = pa.target;
Debug.Log(target);
This will either print to the log as whatever GameObject it is, or null. If it's null, then there is no target.