실행화면 스냅샷.

Unity 5로 '유니티와 C#으로 배우는 게임 개발 교과서' 26장 객체 지향적 사고의 군집행동 예제 따라하기. 완성되었는데 현재는 마우스 있는 쪽으로 추적하는 기능이 먹히지 않고 있는 중.
책에서는 카메라에 부착시킨 BoidSpawner.cs를 빈 게임 오브젝트 생성 뒤 'BoidSpawner'로 명명한 게임오브젝트에 부착하였기에 카메라에서 화면으로 향하는
//마우스 위치 추적
Vector3 mousePos2d = new Vector3 (Input.mousePosition.x, Input.mousePosition.y, mCamera.transform.position.y);
mousePos = mCamera.ScreenToWorldPoint (mousePos2d);
이 부분 코드가 작동하지 않아 생긴 문제였다.

private Camera mCamera; 로 카메라용 변수를 만들고 Start()함수에서
mCamera = GameObject.Find ("_Main Camera").GetComponent<Camera> (); 로 설정하여 문제를 바로 잡다.

16/11/5 월

BoidSpawner.cs=========================================
//Hierarchy탭-BoidsSpawner에 적용.
//보이드들 정해진 수 대로 생성하기, 각종 수치 지정
//마우스 위치 추적하기

using UnityEngine;
using System.Collections;

public class BoidSpawner : MonoBehaviour {
     public static BoidSpawner S; //싱글톤-어디서건 참조 가능.

     public int numBoids = 100;
     public GameObject boidPrefab;
     public float spawnRadius = 100f; //초기 생성시 범위
     public float spawnVelocity = 10f; //생성시 속도
     public float minVelocity = 0f; //최저 속도
     public float maxVelocity = 30f; //최고 속도
     public float nearDist = 30f; //이웃 거리
     public float collisionDist = 5f; //충돌 위험 거리
     public float velocityMatchingAmt = 0.01f; //인접 이웃간 속도 조정용
     public float flockCenteringAmt = 0.15f; //무리 중앙 조정용
     public float collisionAvoidanceAmt = -0.5f; //충돌 회피 정도 조정용
     public float mouseAttractionAmt = 0.01f; //마우스 추적 정도 조정용
     public float mouseAvoidanceAmt = 0.75f; //마우스 회피 정도 조정용
     public float mouseAvoidanceDist = 15f; //마우스 회피 거리
     public float velocityLerpAmt = 0.25f; //속도 보간용

     public bool __________________; //인스펙터 창 구분용
    
     public Vector3 mousePos; //마우스 위치 저장용
     private Camera mCamera; //메인 카메라의 카메라 컴포넌트 저장용

     void Start () {
          //싱글톤 S를 BoidSpawner의 현재 인스턴스로 설정
          S = this;
          //numBoids 만큼 Boid 인스턴스화
          for (int i = 0; i < numBoids; i++) {
               Instantiate (boidPrefab);
          }
          //메인 카메라의 카메라 컴포넌트 참조를 간단히 하기 위한 적용
          mCamera = GameObject.Find ("_Main Camera").GetComponent ();
     }

     void LateUpdate () {
          //마우스 위치 추적
          Vector3 mousePos2d = new Vector3 (Input.mousePosition.x, Input.mousePosition.y,
                                            mCamera.transform.position.y);
          mousePos = mCamera.ScreenToWorldPoint (mousePos2d);
     }
}

Boid.cs=============================================
//Project탭-BoidPref에 적용.
//보이드들의 행동 구현.
//기본적으로 마우스의 위치를 향해 다가가고 마우스와 너무 가까우면 도망간다.
//이동 동안 주변 보이드와 거리와 속도를 유지하며 이동한다.

using UnityEngine;
using System.Collections;
using System.Collections.Generic; //List 사용용

public class Boid : MonoBehaviour {
     //이 정적 리스트는 모든 Boid 인스턴스를 저장, 공유됨
     public static List boids;
     //Rigidbody를 사용치 않고 속도를 직접 처리
     public Vector3 velocity; //현재 속도
     public Vector3 newVelocity; //다음 프레임의 속도
     public Vector3 newPosition;  //다음 프레임의 위치

     public List neighbors; //인접한 모든 Boid
     public List collisionRisks; //너무 가까워 충돌위험인 모든 Boid
     public Boid closest; //가장 가까운 단일 Boid

     void Awake () { //Boid 초기화
          //boids 리스트가 null일 경우 이를 정의.
          if (boids == null) {
               boids = new List();
          }    
          boids.Add (this); //이 Boid를 boids에 추가

          //이 Boid 임의의 위치와 속도 지정.
          Vector3 randPos = Random.insideUnitSphere * BoidSpawner.S.spawnRadius;
          randPos.y = 0; //Boid가 xz 평면에서만 움직이도록 제한
          this.transform.position = randPos;
          velocity = Random.onUnitSphere;
          velocity *= BoidSpawner.S.spawnVelocity;

          //두 리스트 초기화
          neighbors = new List ();
          collisionRisks = new List();

          //this.transform을 Boids 게임오브젝트의 하위 게임오브젝트로 설정
          //수많은 보이드 인스턴스들을 하나의 게임오브젝트 하위에 생성시켜
          //Hierarchy를 깨끗하게 유지하는 팁.*****************
          this.transform.parent = GameObject.Find ("Boids").transform;

          //Boid에 임의의 색 지정, 너무 어둡지 않게 처리
          Color randColor = Color.black;
          while (randColor.r + randColor.g + randColor.b < 1.0f) {
               randColor = new Color(Random.value, Random.value, Random.value);
          }
          Renderer[] rends = gameObject.GetComponentsInChildren ();
          foreach (Renderer r in rends) {
               r.material.color = randColor;
          }
     }

     void Update(){
          //인접한 Boid의 리스트 얻기(이 Boid의 이웃)
          List neighbors = GetNeighbors (this);

          //newVelocity와 newPosition을 현재 값으로 초기화
          newVelocity = velocity;
          newPosition = this.transform.position;

          //**속도일치: 인접 이웃과 비슷하게 조정
          Vector3 neighborVel = GetAverageVelocity (neighbors);
          //BoidSpawner.S 싱글톤에 설정된 필드 활용
          newVelocity += neighborVel * BoidSpawner.S.velocityMatchingAmt;

          //**군집 위치 조정: 이웃의 가운데 방향으로 이동
          Vector3 neighborCenterOffset = GetAveragePosition(neighbors) - this.transform.position;
          newVelocity += neighborCenterOffset * BoidSpawner.S.flockCenteringAmt;

          //**충돌 회피: 너무 가까운 일원과 충돌하지 않게 처리
          Vector3 dist;
          if (collisionRisks.Count > 0) {
               Vector3 collisionAveragePos = GetAveragePosition(collisionRisks);
               dist = collisionAveragePos - this.transform.position;
               newVelocity += dist * BoidSpawner.S.collisionAvoidanceAmt;
          }

          //**마우스 추적: 마우스가 있는 방향으로 이동
          dist = BoidSpawner.S.mousePos - this.transform.position;
          if (dist.magnitude > BoidSpawner.S.mouseAvoidanceDist) {
               newVelocity += dist * BoidSpawner.S.mouseAttractionAmt;
          } else {
               //마우스가 너무 가까이 있으면 빠르게 도망
               newVelocity -= dist.normalized
                    * BoidSpawner.S.mouseAvoidanceDist * BoidSpawner.S.mouseAvoidanceAmt;
          }
          //newVelocity, newPosition은 준비됐지만 LateUpdate()가 설정할 때까지 기다림.
          //이렇게 해야 다른 Boid가 새 값을 계산하기전에 현재의 Boid가 먼저 움직이지 않는다.
     }

     //현 Boid가 움직이기 전 모든 Boid가 자체 업데이트를 마쳐
     //다른 Boid가 어찌 움직일지 결정하기 전에
     //현 Boid를 움직일 때 발생할 수 있는 경합상황 예비용
     void LateUpdate(){
          //선형 보간을 활용, newVelocity 기준으로 현 속도 조정
          velocity = (1 - BoidSpawner.S.velocityLerpAmt) * velocity
               + BoidSpawner.S.velocityLerpAmt * newVelocity;

          //속도가 최소/최대 범위를 벗어나지 않게 처리
          if (velocity.magnitude > BoidSpawner.S.maxVelocity) {
               velocity = velocity.normalized * BoidSpawner.S.maxVelocity;
          }
          if (velocity.magnitude < BoidSpawner.S.minVelocity) {
               velocity = velocity.normalized * BoidSpawner.S.minVelocity;
          }

          //새 위치 결정
          newPosition = this.transform.position + velocity * Time.deltaTime;
          //xz 평면으로 움직임 제한
          newPosition.y = 0;
          //이전 위치에서 새 위치로 방향전환
          this.transform.LookAt (newPosition);
          //newPosition으로 이동
          this.transform.position = newPosition;
     }

     //이웃으로 볼 수 있을만큼 가까운 Boid 찾기
     //boi는 관심 대상 보이드(Boid Of Interest)의 약자
     public List GetNeighbors(Boid boi){
          float closestDist = float.MaxValue; //float이 저장 가능한 최대값
          Vector3 delta;
          float dist;
          neighbors.Clear ();
          collisionRisks.Clear ();

          foreach (Boid b in boids) {
               if(b == boi) continue; //자신이면 패스
               delta = b.transform.position - boi.transform.position;//거리 측정
               dist = delta.magnitude;
               if(dist < closestDist){ //가장 가까운 이웃 찾기
                    closestDist = dist;
                    closest = b;
               }
               //이웃으로 지정한 거리에 속하면 이웃으로 추가
               if(dist < BoidSpawner.S.nearDist){
                    neighbors.Add (b);
               }
               //너무 가까운 거리에 속하면 충돌위험 그룹에 추가
               if(dist < BoidSpawner.S.collisionDist){
                    collisionRisks.Add (b);
               }
          }
          //이웃 없으면 가장 가까운 보이드를 이웃으로 추가
          if (neighbors.Count == 0) {
               neighbors.Add (closest);
          }
          return(neighbors); //이웃 목록 반환
     }

     //List<Boid>에서 이웃들 간 평균 위치 구하기
     public Vector3 GetAveragePosition(List someBoids){
          Vector3 sum = Vector3.zero;
          foreach (Boid b in someBoids) {
               sum += b.transform.position;
          }
          Vector3 center = sum / someBoids.Count;
          return(center);
     }
     //List<Boid>에서 이웃들 간 평균 속도 구하기
     public Vector3 GetAverageVelocity(List someBoids){
          Vector3 sum = Vector3.zero;
          foreach (Boid b in someBoids) {
               sum += b.velocity;
          }
          Vector3 avg = sum / someBoids.Count;
          return(avg);
     }
}