[Learn Unity3D with me] Cutting images in code and loading frame sequence animation, unity3d Cutting
In Cocos2dx, a set of Apis has been encapsulated for processing big charts, but Unity3D does not seem to have similar APIs (well, actually there are, and more powerful functions ), or I cannot find it. However, this is also reasonable. After all, Unity3D is made of 3D, and there are few places to cut images.
Because I use Unity3D for 2D games (PS: It hurts, right? I also think), so I have to consider the two common functions of cropping and playing sequence frames in 2D. My task is to cut the figure below into 16 parts and play it out according to the animation sequence.
When I checked the Unity3D user manual, I found a class: Texture2D, which inherits Texture and is mainly used to create 2D textures, which is very suitable for cropping images.
First, we need to load the big image. There is a very simple method to load the big image, that is, to create a public Texture2D class member variable, then, drag it in the editor and assign a value to it.
Of course, you can also use the dynamic loading of image resources. This method is troublesome. You need to convert the image into a binary stream and assign it to Texture2D.
// Load the image resource void LoadTexture () {using (FileStream file = File. open (Application. dataPath + "/Textures/Player.png", FileMode. open) {using (BinaryReader reader = new BinaryReader (file) {m_texPlayer = new Texture2D (192,256, TextureFormat. ARGB4444, false); texture. loadImage (reader. readBytes (int) file. length ));}}}
After loading, it is necessary to cut. The main idea is that two for loops, one representing the row and one representing the column, and then each pixel is recycled, copy the color in each pixel to the cut Texture2D, and combine Texture2D into a 4x4 matrix array.
The following is the first step:
for (int i = 0; i < m_iMinPicColumnCount; ++i) { for (int j = 0; j < m_iMinPicRowCount; ++j) DePackTexture(i, j); }
The final processing above calls a DePackTexture function, which is used for actual cutting.
// Cut the graph void DePackTexture (int I, int j) {int cur_x = I * m_iMinPicWidth; int cur_y = j * m_iMinPicHeight; Texture2D newTexture = new Texture2D (m_iMinPicWidth, m_iminheight picwidth ); for (int m = cur_y; m <cur_y + m_iMinPicHeight; ++ m) {for (int n = cur_x; n <cur_x + m_iMinPicWidth; ++ n) {newTexture. setPixel (n-cur_x, m-cur_y, m_texPlayer.GetPixel (n, m) ;}} newTexture. apply (); m_texPlayers [I, j] = newTexture ;}Two points are worth noting when you switch the graph. One point is to find a good position, and the other is to execute Apply after the SetPixel operation is executed. Otherwise, it will be ineffective.
Certificate --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The following is frame sequence animation. frame sequence animation actually loads images in a certain order. It is worth noting that all GUI operations must be placed in the OnGUI.
Void DrawAnimation (Texture [,] tex, Rect rect) {// draw the current frame GUI. drawTexture (rect, tex [m_iCurFram, m_iCurAnimation], ScaleMode. stretchToFill, true, 0.0f); // calculate the Time (m_fTime + = Time) of the restricted frame. deltaTime; // if (m_fTime> = 1.0/m_fFps & m_bStop = false) if (m_fTime> =/m_iCurFram = ++ m_iCurFram % m_iMinPicRowCount; // limit frame clearing m_fTime = 0; // if (m_iCurFram> = tex after the total number of frames is exceeded from 0th frames. length) {m_iCurFram = 0 ;}}}
Then there is nothing, and the code is still very simple. The following is a small demo with all the code. It contains the starting and pausing functions of the animation and the frame rate adjustment function of the animation. (The demo address will be attached at the end)
Using UnityEngine; using System. collections; using System; public class CTexture: MonoBehaviour {// public Texture2D m_texPlayer; // private Texture2D [,] m_texPlayers; // private int m_iCurFram of the current frame; // The current animation private int m_iCurAnimation; // The time limit for frame private float m_fTime = 0; // width and height of the thumbnail public int m_iMinPicWidth = 48; public int m_iMinPicHeight = 64; // number of small graphs in a row public int m_iMinPicRowCount = 4; // multiple values exist in one column Public int m_iMinPicColumnCount = 4; // animation control // pause private bool m_bStop = false; // number of private float m_fFps = 4 frames per second; private string m_sFps = ""; void Start () {m_texPlayers = new Texture2D [4, 4]; m_iCurAnimation = 0; m_sFps = m_fFps.ToString (); // load the image resource LoadTexture (); for (int I = 0; I <m_iMinPicColumnCount; ++ I) {for (int j = 0; j <m_iMinPicRowCount; ++ j) DePackTexture (I, j );}} void Update (){ If (Input. getKeyDown (KeyCode. a) {m_iCurAnimation = 2;} if (Input. getKeyDown (KeyCode. s) {m_iCurAnimation = 3;} if (Input. getKeyDown (KeyCode. w) {m_iCurAnimation = 0;} if (Input. getKeyDown (KeyCode. d) {m_iCurAnimation = 1 ;}} void OnGUI () {DrawAnimation (m_texPlayers, new Rect (100,100, m_iMinPicWidth, m_iMinPicHeight); if (GUI. button (new Rect (,), "Start/pause") {m_bStop = False? True: false;} m_sFps = GUI. textField (new Rect (200, 80, 80, 40), m_sFps); if (GUI. button (new Rect (200,150, 50, 40), "application") {m_fFps = float. parse (m_sFps) ;}}// load image resource void LoadTexture () {using (FileStream file = File. open (Application. dataPath + "/Textures/Player.png", FileMode. open) {using (BinaryReader reader = new BinaryReader (file) {m_texPlayer = new Texture2D (192,256, TextureFormat. ARGB4444, false); texture. loadImage (reader. readBytes (int) file. length) ;}}// cut the figure void DePackTexture (int I, int j) {int cur_x = I * m_iMinPicWidth; int cur_y = j * m_iMinPicHeight; texture2D newTexture = new Texture2D (m_iMinPicWidth, m_iMinPicHeight); for (int m = cur_y; m <cur_y + m_iMinPicHeight; ++ m) {for (int n = cur_x; n <cur_x + m_iMinPicWidth; ++ n) {newTexture. setPixel (n-cur_x, m-cur_y, m_texPlayer.GetPixel (n, m) ;}} newTexture. apply (); m_texPlayers [I, j] = newTexture;} void DrawAnimation (Texture [,] tex, Rect rect) {// draw the current frame GUI. drawTexture (rect, tex [m_iCurFram, m_iCurAnimation], ScaleMode. stretchToFill, true, 0.0f); // calculate the Time (m_fTime + = Time) of the restricted frame. deltaTime; // if (m_fTime> = 1.0/m_fFps & m_bStop = false) after the frame limit is exceeded {// m_iCurFram = ++ m_iCurFram % 4; // limit frame clearing m_fTime = 0; // if (m_iCurFram> = tex after the total number of frames is exceeded from 0th frames. length) {m_iCurFram = 0 ;}}}}
Demo address: http://download.csdn.net/detail/baijiajie2012/8092625
How to Create Frame Animation in unity3d
Frame-By-Frame animation is a common animation form (Frame By Frame). Its principle is to break down the animation action in "continuous key frames, that is, different content is drawn frame by frame on each frame of the timeline so that it can be played continuously as an animation. Because the frame sequence content of frame-by-frame animation is different, it not only adds a burden to production, but also produces a large amount of final output files, but its advantages are also obvious: frame-by-frame animation has great flexibility and can express almost any content you want to express. It is similar to the playing mode of a movie and is suitable for performing delicate animations. For example, sudden movements of characters or animals, movements of hair and clothes, walking, talking, and exquisite 3D effects.
How does unity3d achieve the playback of the image sequence by swiping your fingers to the left? If your fingers do not move, move them to the current image and slide them to the right?
C # statement:
// Define the enumeration of a gesture
Public enum Dir: int
{
Left = 0,
Stop,
Right
}
// C # Script Name: Test. cs
Public class Test: MonoBehaviour {
Public GameObject _ plane; // hangs a plane object used to display images
Public float duration = 0.5f; // change an image every 0.5 seconds
Public Texture2D [] _ texAll; // 30 images mounted
Dir _ touchDir; // current gesture
Float curTime = 0;
Int _ index = 0;
Void Update ()
{
// When the operating platform is IOS or Android
If (Application. platform = RuntimePlatform. IPhonePlayer | Application. platform = RuntimePlatform. Android)
{
// When the number of contacts entered is greater than 0 and the finger moves
If (Input. touchCount> 0 & Input. GetTouch (0). phase = TouchPhase. Moved)
{
If (Input. GetTouch (0). deltaPosition. x <0-Mathf. Epsilon)
_ TouchDir = Dir. Left;
Else
_ TouchDir = Dir. Right;
}
// When the number of contacts entered is greater than 0 and the fingers do not move
If (Input. touchCount> 0 & Input. GetTouch (0). phase = TouchPhase. Stationary)
{
_ TouchDir = Dir. Stop;
}
}
// Change the image according to the gesture order or reverse order
If (_ touchDir! = Dir. Stop)
{
If (_ touchDir = Dir. Left)
{
CurTime + = Time. deltaTime;
If (curTime> duration)
{
CurTime = 0;
_ Index = 0? _ TexAll. Length-1: _ index;
_ Plane. renderer. material. mainTexture = _ texAll [_ index --];
}
}
Else
{
CurTime + = Time. deltaTime;
If (curTime> duration)
{
CurTime = 0;
_ Index = _ texAll. Length-1? 0: _ index;
_ Plane. renderer. material. mainTexture = _ texAll [_ index ++];
}
}
}
}
}... Remaining full text>