Unity3D研究院之FBX模型的载入与人物行走动画的播放

 3D 世界中自定义模型的使用恐怕是重中之重,因为系统自身提供的模型肯定是无法满足GD对游戏的策划,所以为了让游戏更加绚丽,我们须要调用美术制作的精品模型与动画,本章MOMO将带领盆友们学习Unity3D中模型的载入与动画的播放,哇咔咔~~

       由于MOMO手头上没有现成的模型,所以我将在Unity3D 官网中下载官方提供的游戏DEMO 中的模型来使用。另外官方提供了很多Unity3D 游戏DEMO,与详细的文档。可以帮助我们学习Unity.有兴趣的盆友可以去看看哈。

下载页面:http://unity3d.com/support/resources/  

本章博文的目的是利用上一章介绍的游戏摇杆来控制人物模型的移动,与行走动画的播放。

 

 

 

如上图所示Create中的文件夹male中存放着模型动画与贴图等,这个应该是美术提供给我们的。然后将整个male用鼠标拖动到左侧3D世界中,通过移动,旋转,缩放将人物模型放置在一个理想的位置。右侧红框内设置模型动画的属性。

Animation  

        idle1  该模型默认动画名称为idle1

Animations 

        size   该模型动画的数量

        Element 该模型的动画名称

Play Automatically 是否自动播放

Animation Physics 是否设置该模型物理碰撞

Animation Only if Visable 是否设置该模型仅自己显示

 

给该模型绑定一个脚本Controller.cs 用来接收摇杆返回的信息更新模型动画。

Controller.cs

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

using UnityEngine;

using System.Collections;

 

public class Controller : MonoBehaviour {

 

//人物的行走方向状态

public const int HERO_UP= 0;

public const int HERO_RIGHT= 1;

public const int HERO_DOWN= 2;

public const int HERO_LEFT= 3;

 

//人物当前行走方向状态

public int state = 0;

 

//备份上一次人物当前行走方向状态

//这里暂时没有用到

public int backState = 0;

 

//游戏摇杆对象

public MPJoystick moveJoystick;  

 

//这个方法只调用一次,在Start方法之前调用

public void Awake() {

 

}

 

//这个方法只调用一次,在Awake方法之后调用

void Start () {

state = HERO_DOWN;

}

 

void Update () {

 

//获取摇杆控制的方向数据 上一章有详细介绍

    float touchKey_x =  moveJoystick.position.x;

    float touchKey_y =  moveJoystick.position.y;  

 

    if(touchKey_x == -1){

       setHeroState(HERO_LEFT);

 

    }else if(touchKey_x == 1){

       setHeroState(HERO_RIGHT);

 

    }  

 

    if(touchKey_y == -1){

        setHeroState(HERO_DOWN);

 

    }else if(touchKey_y == 1){

     setHeroState(HERO_UP);

    }  

 

if(touchKey_x == 0 && touchKey_y ==0){

//松开摇杆后播放默认动画,

//不穿参数为播放默认动画。

animation.Play();

}

 

}

 

public void setHeroState(int newState)

{

 

//根据当前人物方向 与上一次备份方向计算出模型旋转的角度

int rotateValue = (newState - state) * 90;

Vector3 transformValue = new Vector3();

 

//播放行走动画

animation.Play("walk");

 

//模型移动的位移的数值

switch(newState){

case HERO_UP:

transformValue = Vector3.forward * Time.deltaTime;

break;

case HERO_DOWN:

transformValue = -Vector3.forward * Time.deltaTime;

break;

case HERO_LEFT:

transformValue = Vector3.left * Time.deltaTime;

 

break;

case HERO_RIGHT:

transformValue = -Vector3.left * Time.deltaTime;

break;

}

 

        //模型旋转

transform.Rotate(Vector3.up, rotateValue);

 

//模型移动

transform.Translate(transformValue, Space.World);

 

backState = state;

state = newState;

 

}

 

}

 

上一章介绍了javaScript脚本使用游戏摇杆的方法,本章MOMO告诉大家使用C#脚本来使用游戏摇杆,上面我用 Controller.cs  C#脚本来接收系统提供的Joystick.js是肯定无法使用的,须要修改成.cs文件,我在国外的一个网站上看到了一个老外帮我们已经修改了,那么我将他修改后的代码贴出来方便大家学习,有兴趣的朋友可以研究研究。哇咔咔~

MPJoystick.cs

C#

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

using UnityEngine;

 

/**

 

* File: MPJoystick.cs

 

* Author: Chris Danielson of (monkeyprism.com)

 

*

 

// USED TO BE: Joystick.js taken from Penelope iPhone Tutorial

 

//

 

// Joystick creates a movable joystick (via GUITexture) that

 

// handles touch input, taps, and phases. Dead zones can control

 

// where the joystick input gets picked up and can be normalized.

 

//

 

// Optionally, you can enable the touchPad property from the editor

 

// to treat this Joystick as a TouchPad. A TouchPad allows the finger

 

// to touch down at any point and it tracks the movement relatively

 

// without moving the graphic

 

*/

[RequireComponent(typeof(GUITexture))]

 

public class MPJoystick : MonoBehaviour

 

{

 

class Boundary {

 

public Vector2 min = Vector2.zero;

 

public Vector2 max = Vector2.zero;

 

}

private static MPJoystick[] joysticks; // A static collection of all joysticks

 

private static bool enumeratedJoysticks = false;

 

private static float tapTimeDelta = 0.3f; // Time allowed between taps

public bool touchPad;

 

public Vector2 position = Vector2.zero;

 

public Rect touchZone;

 

public Vector2 deadZone = Vector2.zero; // Control when position is output

 

public bool normalize = false; // Normalize output after the dead-zone?

 

public int tapCount;

 

private int lastFingerId = -1; // Finger last used for this joystick

 

private float tapTimeWindow; // How much time there is left for a tap to occur

 

private Vector2 fingerDownPos;

 

//private float fingerDownTime;

 

//private float firstDeltaTime = 0.5f;

private GUITexture gui;

 

private Rect defaultRect; // Default position / extents of the joystick graphic

 

private Boundary guiBoundary = new Boundary(); // Boundary for joystick graphic

 

private Vector2 guiTouchOffset; // Offset to apply to touch input

 

private Vector2 guiCenter; // Center of joystick

void Start() {

 

gui = (GUITexture)GetComponent(typeof(GUITexture));

defaultRect = gui.pixelInset;

 

defaultRect.x += transform.position.x * Screen.width;// + gui.pixelInset.x; // -  Screen.width * 0.5;

 

     defaultRect.y += transform.position.y * Screen.height;// - Screen.height * 0.5;

transform.position = Vector3.zero;

if (touchPad) {

 

// If a texture has been assigned, then use the rect ferom the gui as our touchZone

 

if ( gui.texture )

 

touchZone = defaultRect;

 

} else {

 

guiTouchOffset.x = defaultRect.width * 0.5f;

 

guiTouchOffset.y = defaultRect.height * 0.5f;

// Cache the center of the GUI, since it doesn't change

 

guiCenter.x = defaultRect.x + guiTouchOffset.x;

 

guiCenter.y = defaultRect.y + guiTouchOffset.y;

// Let's build the GUI boundary, so we can clamp joystick movement

 

guiBoundary.min.x = defaultRect.x - guiTouchOffset.x;

 

guiBoundary.max.x = defaultRect.x + guiTouchOffset.x;

 

guiBoundary.min.y = defaultRect.y - guiTouchOffset.y;

 

guiBoundary.max.y = defaultRect.y + guiTouchOffset.y;

 

}

 

}

public Vector2 getGUICenter() {

 

return guiCenter;

 

}

void Disable() {

 

gameObject.active = false;

 

//enumeratedJoysticks = false;

 

}

private void ResetJoystick() {

 

gui.pixelInset = defaultRect;

 

lastFingerId = -1;

 

position = Vector2.zero;

 

fingerDownPos = Vector2.zero;

 

}

private bool IsFingerDown() {

 

return (lastFingerId != -1);

 

}

public void LatchedFinger(int fingerId) {

 

// If another joystick has latched this finger, then we must release it

 

if ( lastFingerId == fingerId )

 

ResetJoystick();

 

}

void Update() {

 

if (!enumeratedJoysticks) {

 

// Collect all joysticks in the game, so we can relay finger latching messages

 

joysticks = (MPJoystick[])FindObjectsOfType(typeof(MPJoystick));

 

enumeratedJoysticks = true;

 

}

int count = Input.touchCount;

if ( tapTimeWindow > 0 )

 

tapTimeWindow -= Time.deltaTime;

 

else

 

tapCount = 0;

if ( count == 0 )

 

ResetJoystick();

 

else

 

{

 

for(int i = 0; i < count; i++) {

 

Touch touch = Input.GetTouch(i);

 

Vector2 guiTouchPos = touch.position - guiTouchOffset;

bool shouldLatchFinger = false;

 

if (touchPad) {

 

if (touchZone.Contains(touch.position))

 

shouldLatchFinger = true;

 

}

 

else if (gui.HitTest(touch.position)) {

 

shouldLatchFinger = true;

 

}

// Latch the finger if this is a new touch

 

if (shouldLatchFinger && (lastFingerId == -1 ¦¦ lastFingerId != touch.fingerId )) {

if (touchPad) {

 

//gui.color.a = 0.15;

 

lastFingerId = touch.fingerId;

 

//fingerDownPos = touch.position;

 

//fingerDownTime = Time.time;

 

}

lastFingerId = touch.fingerId;

 

// Accumulate taps if it is within the time window

 

if ( tapTimeWindow > 0 )

 

tapCount++;

 

else {

 

tapCount = 1;

 

tapTimeWindow = tapTimeDelta;

 

}

// Tell other joysticks we've latched this finger

 

//for (  j : Joystick in joysticks )

 

foreach (MPJoystick j in joysticks) {

 

if (j != this)

 

j.LatchedFinger( touch.fingerId );

 

}

 

}

if ( lastFingerId == touch.fingerId ) {

 

// Override the tap count with what the iPhone SDK reports if it is greater

 

// This is a workaround, since the iPhone SDK does not currently track taps

 

// for multiple touches

 

if ( touch.tapCount > tapCount )

 

tapCount = touch.tapCount;

if ( touchPad ) {

 

// For a touchpad, let's just set the position directly based on distance from initial touchdown

 

position.x = Mathf.Clamp( ( touch.position.x - fingerDownPos.x ) / ( touchZone.width / 2 ), -1, 1 );

 

position.y = Mathf.Clamp( ( touch.position.y - fingerDownPos.y ) / ( touchZone.height / 2 ), -1, 1 );

 

} else {

 

// Change the location of the joystick graphic to match where the touch is

 

Rect r = gui.pixelInset;

 

r.x =  Mathf.Clamp( guiTouchPos.x, guiBoundary.min.x, guiBoundary.max.x );

 

r.y =  Mathf.Clamp( guiTouchPos.y, guiBoundary.min.y, guiBoundary.max.y );

 

gui.pixelInset = r;

 

}

if (touch.phase == TouchPhase.Ended ¦¦ touch.phase == TouchPhase.Canceled)

 

ResetJoystick();

 

}

 

}

 

}

if (!touchPad) {

 

// Get a value between -1 and 1 based on the joystick graphic location

 

position.x = ( gui.pixelInset.x + guiTouchOffset.x - guiCenter.x ) / guiTouchOffset.x;

 

position.y = ( gui.pixelInset.y + guiTouchOffset.y - guiCenter.y ) / guiTouchOffset.y;

 

}

// Adjust for dead zone

 

var absoluteX = Mathf.Abs( position.x );

 

var absoluteY = Mathf.Abs( position.y );

 

if (absoluteX < deadZone.x) {

 

// Report the joystick as being at the center if it is within the dead zone

 

position.x = 0;

 

}

 

else if (normalize) {

 

// Rescale the output after taking the dead zone into account

 

position.x = Mathf.Sign( position.x ) * ( absoluteX - deadZone.x ) / ( 1 - deadZone.x );

 

}

if (absoluteY < deadZone.y) {

 

// Report the joystick as being at the center if it is within the dead zone

 

position.y = 0;

 

}

 

else if (normalize) {

 

// Rescale the output after taking the dead zone into account

 

position.y = Mathf.Sign( position.y ) * ( absoluteY - deadZone.y ) / ( 1 - deadZone.y );

 

}

}

}

导出 build and run  看看在iPhone 上的效果,通过触摸游戏摇杆可以控制人物的上,下,左,右 ,左上,右上,左下,右下 8个方向的移动啦,不错吧,哇咔咔~~

 

 

 

最后欢迎各位盆友可以和MOMO一起讨论Unity3D游戏开发,本来昨天就想发表这篇文章,结果晚上去打高尔夫球连挥N杆,打的回家后浑身酸痛,回家就睡觉啦~希望大家在学习的同时别忘了多运动。哇咔咔~~~ 附上Unity3D工程的下载地址,Xcode项目我就不上传了,须要的自己导出。

 

下载地址:http://vdisk.weibo.com/s/abvxH

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值