The simplest way to create other fish is to copy the model file and modify the local textures to it. In my case, I created a new folder in the 'Content'/'Models' folder called 'OtherFish', and modified the textures so that all of the textures are shades of orange instead of blue. Ensure the new texture files are the same name as the previous ones, and that the 'Content Processor' is set to 'SkinnedModelProcessor', and it will work.
Next up, create a new array of your usermade 'ModelRenderer' type called OtherFishes alongside your other class variables.
ModelRenderer[]OtherFishes=newModelRenderer[16];
And initialise them by placing the following 'for' statement inside your LoadContent() method alongside the others.
//Initialises the NPC fishcurrentModel=Content.Load<Model>("Models\\OtherFish\\FishModel");for(inti=0;i<OtherFishes.Length;i++){OtherFishes[i]=newModelRenderer(currentModel);OtherFishes[i].Translation=newVector3(0f);//Move it to the centre}
In the same way as the original fish we created, we need to place a call to each of these fishes draw and update methods. Place in the following statements, this in alongside the 'FishMen' Update method call;
for(inti=0;i<OtherFishes.Length;i++){OtherFishes[i].Update(gameTime);}
And this alongside the it's Draw call.
for(inti=0;i<OtherFishes.Length;i++){OtherFishes[i].ModelDraw(GraphicsDevice,cameraPosition,cameraTarget,farPlaneDistance);}
This covers the routine aspects to displaying the fish.
Create a new method called 'ResetNPCFish' as below;
//Resets NPC fishesvoidResetNPCFish(intinput){Randomrandom=newRandom();//Allows for the creation of random numbersVector2Boundarys=newVector2(14f);//Defines the boundarys of where the fish start//Rotates the fish so they rotate towards the screenOtherFishes[input].Rotation.Y=(float)((Math.PI/180.0)*180);//Put simply, this will rotate it by 180 degreesOtherFishes[input].Rotation.Z=(float)((Math.PI/180.0)*180);//Moves the fish into a random position defined by the 'Boundarys' variableOtherFishes[input].Translation.X=random.Next((int)Boundarys.X*-1,(int)Boundarys.X);OtherFishes[input].Translation.Y=random.Next((int)Boundarys.Y*-1,(int)Boundarys.Y);//Moves the fish beyond the viewing horizonOtherFishes[input].Translation.Z=random.Next((int)farPlaneDistance+100);OtherFishes[input].PlayAnimation("Frown");}
And place a call to it inside your initialisation routine as below.
//Initialises the NPC fishcurrentModel=Content.Load<Model>("Models\\OtherFish\\FishModel");for(inti=0;i<OtherFishes.Length;i++){OtherFishes[i]=newModelRenderer(currentModel);OtherFishes[i].Translation=newVector3(0f);//Move it to the centreOtherFishes[i].PlayAnimation("Swim");//Play the default swimming animationResetNPCFish(i);}
If you run the game as it is, you should see 16 fish initialised swim past the controllable fish, and little else.

To ensure that the fish swim indefinitely, add the following changes to the 'OtherFishes's update code, which will check the fishes position on the screen, and restart it if needed.
for(inti=0;i<OtherFishes.Length;i++){floatspeed=0.02f;OtherFishes[i].Translation.Z-=speed*(float)gameTime.ElapsedGameTime.TotalMilliseconds;if(OtherFishes[i].Translation.Z<-10f)ResetNPCFish(i);OtherFishes[i].Update(gameTime);}
Run it now, and it will run indefinitely.
Next up, we will place in code which will default the fish to displaying a frown, then when it is bumped into by the player, will change the fishes frowns upside down. Add the following line at the bottom of the 'ResetNPCFish' method.
OtherFishes[input].PlayAnimation("Frown");
To check a collision between the player and the enemy, create the following two new methods.
boolCheckCollision(Vector3PlayerPosition,Vector3NPCPosition){doubleDifferenceNeeded=4;//Feel free to adjust, affects how close the NPC has to be before the expression changesdoubleX=Difference(PlayerPosition.X,NPCPosition.X);X*=X;doubleY=Difference(PlayerPosition.Y,NPCPosition.Y);Y*=Y;doubleZ=Difference(PlayerPosition.Z,NPCPosition.Z);Z*=Z;if(Math.Sqrt(X+Y+Z)<DifferenceNeeded)returntrue;returnfalse;}floatDifference(floatint1,floatint2){if(int1>int2)returnint1-int2;elsereturnint2-int1;}
And the following alongside the other pieces of update code.
if(CheckCollision(FishMen.Translation,OtherFishes[i].Translation))OtherFishes[i].PlayAnimation("Smile");
Play it now, and you should see the fish change when you touch them.