Hello.
I purchased an asset which is a group of birds flocking, and have set it up to be triggered by an image target.
Currently, the birds start flocking when I start the AR camera, and an additional group of birds come flock when triggered by my image target.
I need to get rid of this first flock of birds that are always there even before the image trigger.
I think it has something to do with the code that came with the bird flock asset.
Could someone help?
Here are some of the scripts that were attached.
FlockController.cs
FlockChild.cs
FlockWaypointTrigger.cs
---
/****************************************
FlockController v2.3
Copyright 2015 Unluck Software
www.chemicalbliss.com
v1.01
Flock can now be moved freely on the stage
v1.02
Script is now pragma strict
v1.03
Fixed issue with decreasing bird amount in runtime
v1.04
Added Soar
v1.05
Added Flat Soar and Flat Fly
v2.0
Landing birds waypoint system
v2.01
Added Slow Spawn
v2.1 - 22.09.2014
Added Avoid
Changed to boxed area
v2.11 - 23.09.2014
Added Avoid Up and Down
Added Soar Timeout
Added "Only Birds Above" to landing spots
v2.2 - 05.11.2014
Various improvements to landing
v2,3 - 16.01.2015
Changed _roamers array to list (Use _roamers.Count instead of _roamers.Length)
Added scripts in C#
Roaming area size can now be rectangular
Flock starting position offset
Swapped _posBuffer and transform.position (flock can now be easily moved)
Added grouping/parenting
Cached transforms
Added avoidance layer mask
*****************************************/
using UnityEngine;
using System;
using System.Collections.Generic;
public class FlockController:MonoBehaviour{
public FlockChild _childPrefab; // Assign prefab with FlockChild script attached
public int _childAmount = 250; // Number of objects
public bool _slowSpawn; // Birds will not be instantiated all at once at start
public float _spawnSphere = 3.0f; // Range around the spawner waypoints will created
public float _spawnSphereHeight = 3.0f; // Height of the spawn sphere
public float _spawnSphereDepth = -1.0f;
public float _minSpeed = 6.0f; // minimum random speed
public float _maxSpeed = 10.0f; // maximum random speed
public float _minScale = .7f; // minimum random size
public float _maxScale = 1.0f; // maximum random size
public float _soarFrequency = 0.0f; // How often soar is initiated 1 = always 0 = never
public string _soarAnimation="Soar"; // Animation -required- for soar functionality
public string _flapAnimation="Flap"; // Animation used for flapping
public string _idleAnimation="Idle"; // Animation -required- for sitting idle functionality
public float _diveValue = 7.0f; // Dive depth
public float _diveFrequency = 0.5f; // How often dive 1 = always 0 = never
public float _minDamping = 1.0f; // Rotation tween damping, lower number = smooth/slow rotation (if this get stuck in a loop, increase this value)
public float _maxDamping = 2.0f;
public float _waypointDistance = 1.0f; // How close this can get to waypoint before creating a new waypoint (also fixes stuck in a loop)
public float _minAnimationSpeed = 2.0f; // Minimum animation speed
public float _maxAnimationSpeed = 4.0f; // Maximum animation speed
public float _randomPositionTimer = 10.0f; // ***
public float _positionSphere = 25.0f; // If _randomPositionTimer is bigger than zero the controller will be moved to a random position within this sphere
public float _positionSphereHeight = 25.0f; // Overides height of sphere for more controll
public float _positionSphereDepth = -1.0f;
public bool _childTriggerPos; // Runs the random position function when a child reaches the controller
public bool _forceChildWaypoints; // Forces all children to change waypoints when this changes position
public float _forcedRandomDelay = 1.5f; // Random delay added before forcing new waypoint
public bool _flatFly; // Birds will not rotate upwards as much when flapping
public bool _flatSoar; // Birds will not rotate upwards as much when soaring
public bool _birdAvoid; // Avoid colliders left and right
public int _birdAvoidHorizontalForce = 1000; // How much a bird will react to avoid collision left and right
public bool _birdAvoidDown; // Avoid colliders below
public bool _birdAvoidUp; // Avoid colliders above bird
public int _birdAvoidVerticalForce = 300; // How much a bird will react to avoid collision down and up
public float _birdAvoidDistanceMax = 4.5f; // Maximum distance to check for collision to avoid
public float _birdAvoidDistanceMin = 5.0f; // Minimum distance to check for collision to avoid
public float _soarMaxTime; // Stops soaring after x seconds, use to avoid birds soaring for too long
public LayerMask _avoidanceMask = (LayerMask)(-1); // Avoidance collider mask
public List<FlockChild> _roamers;
public Vector3 _posBuffer;
public int _updateDivisor = 1; //Skip update every N frames (Higher numbers might give choppy results, 3 - 4 on 60fps , 2 - 3 on 30 fps)
public float _newDelta;
public int _updateCounter;
public float _activeChildren;
public bool _groupChildToNewTransform; // Parents fish transform to school transform
public Transform _groupTransform; //
public string _groupName = ""; //
public bool _groupChildToFlock; // Parents fish transform to school transform
public Vector3 _startPosOffset;
public Transform _thisT;
public void Start() {
_thisT = transform;
///FIX FOR UPDATING FROM OLDER VERSION
if(_positionSphereDepth == -1){
_positionSphereDepth = _positionSphere;
}
if(_spawnSphereDepth == -1){
_spawnSphereDepth = _spawnSphere;
}
///FIX
_posBuffer = _thisT.position+_startPosOffset;
if(!_slowSpawn){
AddChild(_childAmount);
}
InvokeRepeating("SetFlockRandomPosition", _randomPositionTimer, _randomPositionTimer);
}
public void AddChild(int amount){
if(_groupChildToNewTransform)InstantiateGroup();
for(int i=0;i<amount;i++){
FlockChild obj = (FlockChild)Instantiate(_childPrefab);
obj._spawner = this;
_roamers.Add(obj);
AddChildToParent(obj.transform);
}
}
public void AddChildToParent(Transform obj){
if(_groupChildToFlock){
obj.parent = transform;
return;
}
if(_groupChildToNewTransform){
obj.parent = _groupTransform;
return;
}
}
public void RemoveChild(int amount){
for(int i=0;i<amount;i++){
FlockChild dObj = _roamers[_roamers.Count-1];
_roamers.RemoveAt(_roamers.Count-1);
Destroy(dObj.gameObject);
}
}
public void Update() {
if(_activeChildren > 0){
if(_updateDivisor > 1){
_updateCounter++;
_updateCounter = _updateCounter % _updateDivisor;
_newDelta = Time.deltaTime*_updateDivisor;
}else{
_newDelta = Time.deltaTime;
}
}
UpdateChildAmount();
}
public void InstantiateGroup(){
if(_groupTransform != null) return;
GameObject g = new GameObject();
_groupTransform = g.transform;
_groupTransform.position = _thisT.position;
if(_groupName != ""){
g.name = _groupName;
return;
}
g.name = _thisT.name + " Fish Container";
}
public void UpdateChildAmount(){
if(_childAmount>= 0 && _childAmount < _roamers.Count){
RemoveChild(1);
return;
}
if (_childAmount > _roamers.Count){
AddChild(1);
}
}
public void OnDrawGizmos() {
if(_thisT == null) _thisT = transform;
if(!Application.isPlaying && _posBuffer != _thisT.position+_startPosOffset){
_posBuffer = _thisT.position+_startPosOffset;
}
if(_positionSphereDepth == -1){
_positionSphereDepth = _positionSphere;
}
if(_spawnSphereDepth == -1){
_spawnSphereDepth = _spawnSphere;
}
Gizmos.color = Color.blue;
Gizmos.DrawWireCube (_posBuffer, new Vector3(_spawnSphere*2, _spawnSphereHeight*2 ,_spawnSphereDepth*2));
Gizmos.color = Color.cyan;
Gizmos.DrawWireCube (_thisT.position, new Vector3((_positionSphere*2)+_spawnSphere*2, (_positionSphereHeight*2)+_spawnSphereHeight*2 ,(_positionSphereDepth*2)+_spawnSphereDepth*2));
}
//Set waypoint randomly inside box
public void SetFlockRandomPosition() {
Vector3 t = Vector3.zero;
t.x = UnityEngine.Random.Range(-_positionSphere, _positionSphere) + _thisT.position.x;
t.z = UnityEngine.Random.Range(-_positionSphereDepth, _positionSphereDepth) + _thisT.position.z;
t.y = UnityEngine.Random.Range(-_positionSphereHeight, _positionSphereHeight) + _thisT.position.y;
// var hit : RaycastHit;
// if (Physics.Raycast(_posBuffer, t, hit, Vector3.Distance(_posBuffer, t))){
// _posBuffer.LookAt(hit.point);
// t = hit.point - (_thisT.forward*-3);
// }
_posBuffer = t;
if(_forceChildWaypoints){
for(int i = 0; i < _roamers.Count; i++) {
(_roamers[i]).Wander(UnityEngine.Random.value*_forcedRandomDelay);
}
}
}
//Instantly destroys all birds
public void destroyBirds() {
for(int i = 0; i < _roamers.Count; i++) {
Destroy((_roamers[i]).gameObject);
}
_childAmount = 0;
_roamers.Clear();
}
}
/**************************************
FlockChild v2.3
Copyright Unluck Software
www.chemicalbliss.com
***************************************/
using UnityEngine;
using System;
public class FlockChild:MonoBehaviour{
[HideInInspector]
public FlockController _spawner; //Reference to the flock controller that spawned this bird
[HideInInspector]
public Vector3 _wayPoint; //Waypoint used to steer towards
public float _speed; //Current speed of bird
[HideInInspector]
public bool _dived =true; //Indicates if this bird has recently performed a dive movement
[HideInInspector]
public float _stuckCounter; //prevents looping around a waypoint by increasing minimum distance to waypoint
[HideInInspector]
public float _damping; //Damping used for steering (steer speed)
[HideInInspector]
public bool _soar = true; // Indicates if this is soaring
[HideInInspector]
public bool _landing; // Indicates if bird is landing or sitting idle
int _lerpCounter; // Used for smoothing motions like speed and leveling rotation
[HideInInspector]
public float _targetSpeed; // Max bird speed
[HideInInspector]
public bool _move = true; // Indicates if bird can fly
public GameObject _model; // Reference to bird model
public Transform _modelT; // Reference to bird model transform (caching tranform to avoid any extra getComponent calls)
[HideInInspector]
public float _avoidValue; //Random value used to check for obstacles. Randomized to lessen uniformed behaviour when avoiding
[HideInInspector]
public float _avoidDistance; //How far from an obstacle this can be before starting to avoid it
float _soarTimer;
bool _instantiated;
static int _updateNextSeed = 0;
int _updateSeed = -1;
[HideInInspector]
public bool _avoid = true;
public Transform _thisT;
public void Start(){
FindRequiredComponents(); //Check if references to transform and model are set (These should be set in the prefab to avoid doind this once a bird is spawned, click "Fill" button in prefab)
Wander(0.0f);
SetRandomScale();
_thisT.position = findWaypoint();
RandomizeStartAnimationFrame();
InitAvoidanceValues();
_speed = _spawner._minSpeed;
_spawner._activeChildren++;
_instantiated = true;
if(_spawner._updateDivisor > 1){
int _updateSeedCap = _spawner._updateDivisor -1;
_updateNextSeed++;
this._updateSeed = _updateNextSeed;
_updateNextSeed = _updateNextSeed % _updateSeedCap;
}
}
public void Update() {
//Skip frames
if (_spawner._updateDivisor <=1 || _spawner._updateCounter == _updateSeed){
SoarTimeLimit();
CheckForDistanceToWaypoint();
RotationBasedOnWaypointOrAvoidance();
LimitRotationOfModel();
}
}
public void OnDisable() {
CancelInvoke();
_spawner._activeChildren--;
}
public void OnEnable() {
if(_instantiated){
_spawner._activeChildren++;
if(_landing){
_model.GetComponent<Animation>().Play(_spawner._idleAnimation);
}else{
_model.GetComponent<Animation>().Play(_spawner._flapAnimation);
}
}
}
public void FindRequiredComponents(){
if(_thisT == null) _thisT = transform;
if(_model == null) _model = _thisT.FindChild("Model").gameObject;
if(_modelT == null) _modelT = _model.transform;
}
public void RandomizeStartAnimationFrame(){
foreach(AnimationState state in _model.GetComponent<Animation>()) {
state.time = UnityEngine.Random.value * state.length;
}
}
public void InitAvoidanceValues(){
_avoidValue = UnityEngine.Random.Range(.3f, .1f);
if(_spawner._birdAvoidDistanceMax != _spawner._birdAvoidDistanceMin){
_avoidDistance = UnityEngine.Random.Range(_spawner._birdAvoidDistanceMax , _spawner._birdAvoidDistanceMin);
return;
}
_avoidDistance = _spawner._birdAvoidDistanceMin;
}
public void SetRandomScale(){
float sc = UnityEngine.Random.Range(_spawner._minScale, _spawner._maxScale);
_thisT.localScale=new Vector3(sc,sc,sc);
}
//Soar Timeout - Limits how long a bird can soar
public void SoarTimeLimit(){
if(this._soar && _spawner._soarMaxTime > 0){
if(_soarTimer > _spawner._soarMaxTime){
this.Flap();
_soarTimer = 0.0f;
}else {
_soarTimer+=_spawner._newDelta;
}
}
}
public void CheckForDistanceToWaypoint(){
if(!_landing && (_thisT.position - _wayPoint).magnitude < _spawner._waypointDistance+_stuckCounter){
Wander(0.0f);
_stuckCounter=0.0f;
}else if(!_landing){
_stuckCounter+=_spawner._newDelta;
}else{
_stuckCounter=0.0f;
}
}
public void RotationBasedOnWaypointOrAvoidance(){
Vector3 lookit = _wayPoint - _thisT.position;
if(_targetSpeed > -1 && lookit != Vector3.zero){
Quaternion rotation = Quaternion.LookRotation(lookit);
_thisT.rotation = Quaternion.Slerp(_thisT.rotation, rotation, _spawner._newDelta * _damping);
}
if(_spawner._childTriggerPos){
if((_thisT.position - _spawner._posBuffer).magnitude < 1){
_spawner.SetFlockRandomPosition();
}
}
_speed = Mathf.Lerp(_speed, _targetSpeed, _lerpCounter * _spawner._newDelta *.05f);
_lerpCounter++;
//Position forward based on object rotation
if(_move){
_thisT.position += _thisT.forward*_speed*_spawner._newDelta;
if(_avoid && _spawner._birdAvoid)
Avoidance();
}
}
public bool Avoidance() {
RaycastHit hit = new RaycastHit();
Vector3 fwd = _modelT.forward;
bool r = false;
Quaternion rot = Quaternion.identity;
Vector3 rotE = Vector3.zero;
Vector3 pos = Vector3.zero;
pos = _thisT.position;
rot = _thisT.rotation;
rotE = _thisT.rotation.eulerAngles;
if (Physics.Raycast(_thisT.position, fwd+(_modelT.right*_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){
rotE.y -= _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
rot.eulerAngles = rotE;
_thisT.rotation = rot;
r= true;
}else if (Physics.Raycast(_thisT.position,fwd+(_modelT.right*-_avoidValue), out hit, _avoidDistance, _spawner._avoidanceMask)){
rotE.y += _spawner._birdAvoidHorizontalForce*_spawner._newDelta*_damping;
rot.eulerAngles = rotE;
_thisT.rotation = rot;
r= true;
}
if (_spawner._birdAvoidDown && !this._landing && Physics.Raycast(_thisT.position, -Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){
rotE.x -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
rot.eulerAngles = rotE;
_thisT.rotation = rot;
pos.y += _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
_thisT.position = pos;
r= true;
}else if (_spawner._birdAvoidUp && !this._landing && Physics.Raycast(_thisT.position, Vector3.up, out hit, _avoidDistance, _spawner._avoidanceMask)){
rotE.x += _spawner._birdAvoidVerticalForce*_spawner._newDelta*_damping;
rot.eulerAngles = rotE;
_thisT.rotation = rot;
pos.y -= _spawner._birdAvoidVerticalForce*_spawner._newDelta*.01f;
_thisT.position = pos;
r= true;
}
return r;
}
public void LimitRotationOfModel(){
Quaternion rot = Quaternion.identity;
Vector3 rotE = Vector3.zero;
rot = _modelT.localRotation;
rotE = rot.eulerAngles;
if((_soar && _spawner._flatSoar|| _spawner._flatFly && !_soar)&& _wayPoint.y > _thisT.position.y||_landing){
rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, -_thisT.localEulerAngles.x, _lerpCounter * _spawner._newDelta * .75f);
rot.eulerAngles = rotE;
_modelT.localRotation = rot;
}else{
rotE.x = Mathf.LerpAngle(_modelT.localEulerAngles.x, 0.0f, _lerpCounter * _spawner._newDelta * .75f);
rot.eulerAngles = rotE;
_modelT.localRotation = rot;
}
}
public void Wander(float delay){
if(!_landing){
_damping = UnityEngine.Random.Range(_spawner._minDamping, _spawner._maxDamping);
_targetSpeed = UnityEngine.Random.Range(_spawner._minSpeed, _spawner._maxSpeed);
_lerpCounter = 0;
Invoke("SetRandomMode", delay);
}
}
public void SetRandomMode(){
CancelInvoke("SetRandomMode");
if(!_dived && UnityEngine.Random.value < _spawner._soarFrequency){
Soar();
}else if(!_dived && UnityEngine.Random.value < _spawner._diveFrequency){
Dive();
}else{
Flap();
}
}
public void Flap(){
if(_move){
if(this._model != null) _model.GetComponent<Animation>().CrossFade(_spawner._flapAnimation, .5f);
_soar=false;
animationSpeed();
_wayPoint = findWaypoint();
_dived = false;
}
}
public Vector3 findWaypoint(){
Vector3 t = Vector3.zero;
t.x = UnityEngine.Random.Range(-_spawner._spawnSphere, _spawner._spawnSphere) + _spawner._posBuffer.x;
t.z = UnityEngine.Random.Range(-_spawner._spawnSphereDepth, _spawner._spawnSphereDepth) + _spawner._posBuffer.z;
t.y = UnityEngine.Random.Range(-_spawner._spawnSphereHeight, _spawner._spawnSphereHeight) + _spawner._posBuffer.y;
return t;
}
public void Soar(){
if(_move){
_model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
_wayPoint= findWaypoint();
_soar = true;
}
}
public void Dive(){
if(_spawner._soarAnimation!=null){
_model.GetComponent<Animation>().CrossFade(_spawner._soarAnimation, 1.5f);
}else{
foreach(AnimationState state in _model.GetComponent<Animation>()) {
if(_thisT.position.y < _wayPoint.y +25){
state.speed = 0.1f;
}
}
}
_wayPoint= findWaypoint();
_wayPoint.y -= _spawner._diveValue;
_dived = true;
}
public void animationSpeed(){
foreach(AnimationState state in _model.GetComponent<Animation>()) {
if(!_dived && !_landing){
state.speed = UnityEngine.Random.Range(_spawner._minAnimationSpeed, _spawner._maxAnimationSpeed);
}else{
state.speed = _spawner._maxAnimationSpeed;
}
}
}
}
using UnityEngine;
using System;
public class FlockWaypointTrigger:MonoBehaviour{
public float _timer =1.0f;
public FlockChild _flockChild;
public void Start() {
if(_flockChild == null)
_flockChild = transform.parent.GetComponent<FlockChild>();
float timer = UnityEngine.Random.Range(_timer, _timer*3);
InvokeRepeating("Trigger", timer, timer);
}
public void Trigger() {
_flockChild.Wander(0.0f);
}
}
Hello.
I purchased an asset which is a group of birds flocking, and have set it up to be triggered by an image target.
Currently, the birds start flocking when I start the AR camera, and an additional group of birds come flock when triggered by my image target.
I need to get rid of this first flock of birds that are always there even before the image trigger.
I think it has something to do with the code that came with the bird flock asset.
Could someone help?
Here are some of the scripts that were attached.
FlockController.cs
FlockChild.cs
FlockWaypointTrigger.cs
---