private void SpawnRandomFlockSpherical(Vector3 center, FlockData[] storeTo, int index) { Vector3 randomDirection = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; Vector3 randomOrientation = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; Vector3 pos = center + (randomDirection * Random.Range(0f, FlockingMaxSpawnRadius)); FlockData flock = new FlockData(); flock.position = pos; flock.currentDirection = randomOrientation; flock.targetDirection = randomOrientation; flock.targetVelocity = Random.Range(FlockingStartVelocityMin, FlockingStartVelocityMax); if (index < destinationPoints.Length) { flock.destinationPoint = destinationPoints[index]; } storeTo[index] = flock; }
// Update is called once per frame void Update() { //--------------- Get particles to alter -------------------- ParticleSystem.Particle[] particles = new ParticleSystem.Particle[flockParticleEmitter.particleCount]; flockParticleEmitter.GetParticles(particles); //--------------- Get particles to alter -------------------- int i = Mathf.Min(flockers.Length, particles.Length); //Should be the same, but hey... while (--i > -1) { //--------------- Update Flocking positions based on Velocity and targetDirection -------------------- FlockData flock = flockers[i]; flock.currentDirection = Vector3.Slerp(flock.currentDirection, flock.targetDirection, Time.deltaTime * FlockingSteeringSpeed); flock.position += flock.currentDirection * (Time.deltaTime * flock.currentVelocity); flock.currentColor = Color.Lerp(flock.currentColor, flock.targetColor, Time.deltaTime * ParticleColorLerpSpeed); //--------------- Update Flocking positions based on Velocity and targetDirection -------------------- //--------------- Update assosiated particle -------------------- particles[i].position = flock.position; particles[i].remainingLifetime = float.MaxValue; particles[i].color = flock.currentColor; particles[i].size = ParticleSize; //--------------- Update assosiated particle -------------------- if (FlockingDebugMode) { Debug.DrawRay(flock.position, flock.targetDirection * 2f, Color.white); Debug.DrawRay(flock.position, flock.currentDirection * 2f, Color.red); } } flockParticleEmitter.SetParticles(particles, particles.Length); }
//--------------- IThreadWorker Implementation -------------------- public void ExecuteThreadedWork() { startWorkIndex = Mathf.Clamp(startWorkIndex, 0, AllFlocks.Length); endWorkIndex = Mathf.Clamp(endWorkIndex, 0, AllFlocks.Length); //--------------- Creat list with indexes -------------------- int[] randomIndexes = new int[AllFlocks.Length]; int i = AllFlocks.Length; while (--i > -1) { randomIndexes[i] = i; } //--------------- Creat list with indexes -------------------- for (i = startWorkIndex; i < endWorkIndex && !isAborted; i++) { //--------------- Shuffle indexes every-something-flocks -------------------- if ((float)i % (float)maxRandomSiblingsTested == 0f) { randomIndexes.Shuffle(); } //--------------- Shuffle indexes every-something-flocks -------------------- FlockData flock = AllFlocks[i]; if (flock.position.y < 0f) //Through the ground.... { flock.position.y = -flock.position.y; flock.targetDirection.y = Mathf.Abs(flock.targetDirection.y); flock.currentDirection = flock.targetDirection; flock.currentColor = flock.targetColor = new Color(1f, 1f, 0f, 0.65f); flock.currentVelocity = flock.targetVelocity; } else { Vector3 toCenterVec = universeCenter - flock.position; if (toCenterVec.sqrMagnitude > maxBoundsRadius * maxBoundsRadius) //If outside of univere limits { flock.targetDirection = toCenterVec.normalized; flock.targetColor = new Color(1f, 0f, 1f, 0.25f); flock.currentVelocity = flock.targetVelocity; } else { //--------------- Check for Collisions -------------------- bool isColliding = false; int j = AllColliders.Length; Vector3 collisionAvoidenceDir = Vector3.zero; while (--j > -1 && !isAborted) { EnvironmentCollider coll = AllColliders[j]; Vector3 diffVec = coll.position - flock.position; if (diffVec.sqrMagnitude < coll.radiusSqr) { isColliding = true; Vector3 invDiff = -diffVec.normalized; Vector3 reflectionDir = FlockHelper.ReflectVector(invDiff, flock.currentDirection); collisionAvoidenceDir += reflectionDir; flock.position = coll.position + (invDiff * coll.radius); } } //--------------- Check for Collisions -------------------- if (isColliding) //If Colliding { flock.targetDirection = flock.currentDirection = collisionAvoidenceDir.normalized; flock.currentColor = flock.targetColor = new Color(1f, 0.1f, 0f, 0.85f); flock.currentVelocity = flock.targetVelocity * 2f; } else { Vector3 diffDestionation = flock.destinationPoint - flock.position; if (diffDestionation.sqrMagnitude < destinationAttractRadiusSqr) //If close to unique target point... { flock.targetDirection = diffDestionation.normalized; float lerpT = Mathf.Clamp01(diffDestionation.magnitude / destinationReachedRadius); flock.currentVelocity = flock.targetVelocity * lerpT; flock.targetColor = Color.Lerp(new Color(0f, 1f, 0f, 1f), new Color(1f, 1f, 1f, 0.15f), lerpT); } else { Vector3 combinedDirection = flock.targetDirection; Vector3 combinedColor = Vector3.zero; j = Mathf.Min(AllFlocks.Length, maxRandomSiblingsTested); while (--j > -1 && !isAborted) { //--------------- Get a random sibling -------------------- int randomIndex = randomIndexes[j]; if (i == randomIndex) { continue; } FlockData sibling = AllFlocks[randomIndex]; //--------------- Get a random sibling -------------------- Vector3 diffVec = sibling.position - flock.position; float distSqr = diffVec.sqrMagnitude; if (distSqr < seperationRadiusSqr) { combinedDirection += Vector3.Cross(flock.currentDirection, diffVec.normalized) * seperationWeight; combinedColor.y += seperationWeight; //y == green; } //else if (distSqr < alignmentRadiusSqr) if (distSqr < alignmentRadiusSqr) { combinedDirection += sibling.currentDirection * alignmentWeight; combinedColor.z += alignmentWeight; //z == blue; } //else if (distSqr < cohesionRadiusSqr) if (distSqr < cohesionRadiusSqr) { combinedDirection += diffVec.normalized * cohesionWeight; combinedColor += new Vector3(cohesionWeight, cohesionWeight, cohesionWeight); //Add white } } flock.targetDirection = combinedDirection.normalized; flock.currentVelocity = flock.targetVelocity; combinedColor.Normalize(); flock.targetColor = new Color(combinedColor.x, combinedColor.y, combinedColor.z, 0.15f); } } } } } }
private void SpawnRandomFlockSpherical(Vector3 center, FlockData[] storeTo, int index) { Vector3 randomDirection = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; Vector3 randomOrientation = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), Random.Range(-1f, 1f)).normalized; Vector3 pos = center + (randomDirection * Random.Range(0f, FlockingMaxSpawnRadius)); FlockData flock = new FlockData(); flock.position = pos; flock.currentDirection = randomOrientation; flock.targetDirection = randomOrientation; flock.targetVelocity = Random.Range(FlockingStartVelocityMin, FlockingStartVelocityMax); if (index < destinationPoints.Length) flock.destinationPoint = destinationPoints[index]; storeTo[index] = flock; }