Skip to content

Commit 3fefbe9

Browse files
committed
Merge branch 'dev/1.3' of https://github.com/galacean/engine into feat/shaderlab-relative-include
2 parents c92e674 + 921d3bc commit 3fefbe9

File tree

257 files changed

+11386
-22
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

257 files changed

+11386
-22
lines changed

docs/en/_meta.json

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"index": {
3+
"title": "Homepage",
4+
"display": "hidden"
5+
},
6+
"quick-start": {
7+
"title": "Quick Start",
8+
"theme": {
9+
"collapse": true
10+
}
11+
},
12+
"interface": {
13+
"title": "Interface",
14+
"theme": {
15+
"collapse": true
16+
}
17+
},
18+
"core": {
19+
"title": "Core",
20+
"theme": {
21+
"collapse": true
22+
}
23+
},
24+
"assets": {
25+
"title": "Assets",
26+
"theme": {
27+
"collapse": true
28+
}
29+
},
30+
"camera": {
31+
"title": "Camera",
32+
"theme": {
33+
"collapse": true
34+
}
35+
},
36+
"background": {
37+
"title": "Background",
38+
"theme": {
39+
"collapse": true
40+
}
41+
},
42+
"lighting": {
43+
"title": "Lighting",
44+
"theme": {
45+
"collapse": true
46+
}
47+
},
48+
"ecosystem": {
49+
"title": "Ecosystem",
50+
"theme": {
51+
"collapse": true
52+
}
53+
}
54+
}

docs/en/animation/animator.md

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
order: 3
3+
title: Animation Control Component
4+
type: Animation
5+
label: Animation
6+
---
7+
8+
The Animation Control Component ([Animator](/apis/core/#Animator)) is responsible for reading data from an [Animator Controller](/en/docs/animation-animatorController) ([AnimatorController](/apis/core/#AnimatorController)) and playing its content.
9+
10+
### Parameter Description
11+
12+
| Property | Description |
13+
| :------------------ | :----------------------------- |
14+
| animatorController | Binds the `AnimatorController` asset |
15+
16+
## Editor Usage
17+
18+
1. When we drag a model into the scene, the model is displayed in its initial pose but does not play any animation. We need to add an Animation Control Component ([Animator](/apis/core/#Animator}) to the model entity.
19+
20+
![2](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*kuSLTaxomrUAAAAAAAAAAAAADsJ_AQ/original)
21+
22+
2. The Animation Control Component ([Animator](/apis/core/#Animator}) needs to be bound to an [Animator Controller](/en/docs/animation-animatorController}) asset. We create and bind it.
23+
24+
![3](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*irT7SZvw4N8AAAAAAAAAAAAADsJ_AQ/original)
25+
26+
![4](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*VtX3RJR8kdMAAAAAAAAAAAAADsJ_AQ/original)
27+
28+
3. Now you can play the animations in the [Animator Controller](/en/docs/animation-animatorController) in your exported project using `animator.play`.
29+
30+
If you haven't added an Animation Control Component ([Animator](/apis/core/#Animator}) to the entity, Galacean Engine will create one for you by default, and the [Animator Controller](/en/docs/animation-animatorController}) will automatically add all animation clips of the model. Of course, you can achieve more functionality through the [Animator Controller](/en/docs/animation-animatorController}).
31+
32+
## Script Usage
33+
34+
> Before using scripts, it is recommended to read the [Animation System Composition](/en/docs/animation-system) document to help you better understand the animation system's operational logic.
35+
36+
### Play Animation
37+
38+
After loading a GLTF model, the engine will automatically add an Animator component to the model and include the animation clips from the model. You can directly access the Animator component on the root entity of the model and play a specific animation.
39+
40+
```typescript
41+
engine.resourceManager
42+
.load<GLTFResource>(
43+
"https://gw.alipayobjects.com/os/bmw-prod/5e3c1e4e-496e-45f8-8e05-f89f2bd5e4a4.glb"
44+
)
45+
.then((asset) => {
46+
const { defaultSceneRoot } = asset;
47+
rootEntity.addChild(defaultSceneRoot);
48+
const animator = defaultSceneRoot.getComponent(Animator);
49+
animator.play("run");
50+
});
51+
```
52+
53+
#### Control Playback Speed
54+
55+
You can control the playback speed of the animation using the [speed](/apis/core/#Animator-speed) property. The `speed` default value is `1.0`, where a higher value speeds up the playback and a lower value slows it down. When the value is negative, the animation plays in reverse.
56+
57+
```typescript
58+
animator.speed = 2.0;
59+
```
60+
61+
#### Pause/Resume Playback
62+
63+
You can control the pause and play of the animation by setting the Animator's [enabled](/apis/core/#Animator-enabled) property.
64+
65+
```typescript
66+
// 暂停
67+
animator.enabled = false;
68+
// 恢复
69+
animator.enabled = true;
70+
```
71+
72+
If you want to pause a specific animation state, you can achieve this by setting its speed to 0.
73+
74+
```typescript
75+
const state = animator.findAnimatorState("xxx");
76+
state.speed = 0;
77+
```
78+
79+
#### Play a Specific Animation State
80+
81+
<playground src="skeleton-animation-play.ts"></playground>
82+
83+
You can use the [play](/apis/core/#Animator-play) method to play a specific AnimatorState. The parameter is the `name` of the AnimatorState. For more details on other parameters, refer to the [API documentation](/apis/core/#Animator-play}).
84+
85+
```typescript
86+
animator.play("run");
87+
```
88+
89+
If you need to start playing at a certain moment in the animation, you can do so as follows:
90+
91+
```typescript
92+
const layerIndex = 0;
93+
const normalizedTimeOffset = 0.5; // Normalized time
94+
animator.play("run", layerIndex, normalizedTimeOffset);
95+
```
96+
97+
### Get the current playing animation state
98+
99+
You can use the [getCurrentAnimatorState](/apis/core/#Animator-getCurrentAnimatorState) method to get the currently playing AnimatorState. The parameter is the index of the layer where the animation state is located, see [API documentation](/apis/core/#Animator-getCurrentAnimatorState) for details. After obtaining it, you can set the properties of the animation state, such as changing the default loop playback to once.
100+
101+
```typescript
102+
const currentState = animator.getCurrentAnimatorState(0);
103+
// 播放一次
104+
currentState.wrapMode = WrapMode.Once;
105+
// 循环播放
106+
currentState.wrapMode = WrapMode.Loop;
107+
```
108+
109+
### Get the animation state
110+
111+
You can use the [findAnimatorState](/apis/core/#Animator-findAnimatorState) method to get the AnimatorState with the specified name. See [API documentation](/apis/core/#Animator-getCurrentAnimatorState) for details. After obtaining it, you can set the properties of the animation state, such as changing the default loop playback to once.
112+
113+
```typescript
114+
const state = animator.findAnimatorState("xxx");
115+
// 播放一次
116+
state.wrapMode = WrapMode.Once;
117+
// 循环播放
118+
state.wrapMode = WrapMode.Loop;
119+
```
+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
---
2+
order: 2
3+
title: Animation Controller
4+
type: Animation
5+
label: Animation
6+
---
7+
8+
The Animation Controller ([AnimatorController](/apis/core/#AnimatorController)) is used to organize [animation clips](/en/docs/animation-clip) ([AnimationClip](/apis/core/#AnimationClip)) to achieve more flexible and rich animation effects.
9+
10+
## Editor Usage
11+
12+
### Basic Usage
13+
14+
Through the editor of the animation controller, users can organize the playback logic of [animation clips](/en/docs/animation-clip}).
15+
16+
1. Prepare the animation clips ([Create animation clips](/en/docs/animation-clip}))
17+
18+
![1](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*Qc8sQ6iJd8IAAAAAAAAAAAAADsJ_AQ/original)
19+
20+
2. To organize the playback of these animation clips, we need to create an animation controller ([AnimatorController](/apis/core/#AnimatorController})) asset
21+
22+
![3](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*irT7SZvw4N8AAAAAAAAAAAAADsJ_AQ/original)
23+
24+
3. The newly created animation controller has no data, we need to edit it, double-click the asset, and add an AnimatorState to it
25+
26+
![5](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*BcYXSI6OTyoAAAAAAAAAAAAADsJ_AQ/original)
27+
28+
4. Click on AnimatorState to bind an animation clip to it
29+
30+
![6](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*KwFzRZCmbxoAAAAAAAAAAAAADsJ_AQ/original)
31+
32+
5. Bind this animation controller ([AnimatorController](/apis/core/#AnimatorController})) asset to the [animation control component](/en/docs/animation-animator})
33+
34+
![4](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*VtX3RJR8kdMAAAAAAAAAAAAADsJ_AQ/original)
35+
36+
6. Now you can play the `run` animation by `animator.play("New State")` in your exported project
37+
38+
You can achieve more functions through the editor of the animation controller:
39+
40+
### Default Play
41+
42+
Connect AnimatorState to `entry`, and the animation on it will automatically play when your exported project runs, without the need to call `animator.play`. At the same time, you will see the model in the editor also start playing the animation.
43+
44+
![2](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*t2JlQ7PGqikAAAAAAAAAAAAADsJ_AQ/original)
45+
46+
### Animation Transition
47+
48+
Connect two `AnimatorState` you want to transition between to achieve the effect of animation transition. Click on the line between the two animations to modify the parameters of the animation transition for adjustment.
49+
50+
![animationcrossfade](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*7_OFQqABtc0AAAAAAAAAAAAADsJ_AQ/original)
51+
52+
#### Parameter Description
53+
54+
| Property | Function Description |
55+
| :------- | :------------------------------------------------------------------- |
56+
| duration | Transition duration, time is normalized time relative to the target state, default value is 1.0 |
57+
| offset | Forward offset time of the target state, time is normalized time relative to the target state, default value is 0 |
58+
| exitTime | Start state transition start time, time is normalized time relative to the start state, default value is 0.3 |
59+
60+
### Animation Layering
61+
62+
The Galacean engine supports multi-layer animation layering. Animation layering is achieved through blending between `AnimatorControllerLayer`. The first layer is the base animation layer, modifying its weight and blending mode will not take effect.
63+
64+
Double-click the `AnimatorController` resource file to edit the animation, add a layer, and connect the blended actions to `entry`.
65+
66+
67+
![animationadditive](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*vF7fS6mRnmYAAAAAAAAAAAAADsJ_AQ/original)
68+
69+
Sometimes you may want to achieve a fixed pose, you need to trim the animation slices provided by the designer, you can modify the `StartTime` and `EndTime` of `AnimatorState`, click on `AnimatorState` to edit it:
70+
71+
![1](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*JNFGTboEM5QAAAAAAAAAAAAADsJ_AQ/original)
72+
73+
| Property | Description |
74+
| :------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75+
| Name | Modify the name of `AnimatorState`, the name should be **unique** in the layer it belongs to. |
76+
| AnimationClip | Used to bind the `AnimationClip` asset, `AnimationClip` stores the animation data of the model. |
77+
| WrapMode | Whether `AnimatorState` loops or plays once, default is `Once` which means play once. |
78+
| Speed | The playback speed of `AnimatorState`, default value is 1.0, the larger the value, the faster the animation speed. |
79+
| StartTime | Where `AnimatorState` starts playing from in the `AnimationClip`, time is normalized time relative to the duration of `AnimationClip`. Default is 0, starting from the beginning. For example, if the value is 1.0, it is the last frame state of `AnimationClip`. |
80+
| EndTime | Where `AnimatorState` stops playing in the `AnimationClip`, time is normalized time relative to the duration of `AnimationClip`. Default is 1.0, playing until the end. |
81+
82+
You can also adjust the weight of the `Layer` in the blend by modifying the `Weight` parameter of the `Layer`, and modify the blending mode by changing the `Blending`.
83+
84+
![animationadditive2](https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*_3aNSKP44FgAAAAAAAAAAAAADsJ_AQ/original)
85+
86+
| Property | Description |
87+
| :-------- | :-------------------------------------------------------------------------- |
88+
| Name | The name of this layer. |
89+
| Weight | The blend weight of this layer, default value is 1.0. |
90+
| Blending | The blending mode of this layer, `Additive` for additive mode, `Override` for override mode, default is `Override`. |
91+
92+
## Script Usage
93+
94+
> Before using the script, it is recommended to read the [Animation System Composition](/en/docs/animation-system) documentation to help you better understand the operation logic of the animation system.
95+
96+
### Default Playback
97+
98+
You can set the default playback animation for the layer by setting the [defaultState](/apis/core/#AnimatorStateMachine-defaultState) of the AnimatorStateMachine. This way, when Animator `enabled=true`, you do not need to call the `play` method to play the default animation.
99+
100+
```typescript
101+
const layers = animator.animatorController.layers;
102+
layers[0].stateMachine.defaultState = animator.findAnimatorState("walk");
103+
layers[1].stateMachine.defaultState = animator.findAnimatorState("sad_pose");
104+
layers[1].blendingMode = AnimatorLayerBlendingMode.Additive;
105+
```
106+
107+
### Animation Transition
108+
109+
You can implement transitions between animation states by adding `AnimatorTransition` to `AnimatorState`.
110+
111+
```typescript
112+
const walkThenRunState = animatorStateMachine.addState("walkThenRun");
113+
walkThenRunState.clip = walkClip;
114+
const runState = animatorStateMachine.addState("run");
115+
runState.clip = runClip;
116+
const transition = new AnimatorStateTransition();
117+
transition.duration = 1;
118+
transition.offset = 0;
119+
transition.exitTime = 0.5;
120+
transition.destinationState = runState;
121+
walkThenRunState.addTransition(transition);
122+
animator.play("walkThenRun");
123+
```
124+
125+
By doing this, every time you play the `walkThenRun` animation in the layer of the animation state machine, it will transition from the `walk` animation to the `run` animation halfway through the `walk` animation.
126+
127+
### Animation Overlay
128+
129+
To overlay animations, add the desired animation state to another layer and set its blending mode to `AnimatorLayerBlendingMode.Additive` to achieve the animation overlay effect.
130+
131+
<playground src="skeleton-animation-additive.ts"></playground>
132+
133+
### Animation Data
134+
135+
#### Setting Animation Data
136+
137+
You can set the animation data of the animator controller using the [animatorController](/apis/core/#Animator-animatorController) property. A default AnimatorController will be automatically added when a GLTF model is loaded.
138+
139+
```typescript
140+
animator.animatorController = new AnimatorController();
141+
```
142+
143+
#### Reusing Animation Data
144+
145+
Sometimes the animation data of a model is stored in another model, and you can import and use it as follows:
146+
147+
<playground src="skeleton-animation-reuse.ts"></playground>
148+
149+
In addition, the [AnimatorController](/apis/core/#AnimatorController) of the Animator is a class for storing data and does not contain runtime data. Based on this design, as long as the hierarchical structure and naming of the **skeleton nodes** of the model bound to the Animator component are the same, we can reuse the animation data.
150+
151+
```typescript
152+
const animator = model1.getComponent(Animator);
153+
animator.animatorController = model2.getComponent(Animator).animatorController;
154+
```
155+
156+
### State Machine Script
157+
158+
<playground src="animation-stateMachineScript.ts"></playground>
159+
160+
The state machine script provides users with lifecycle hook functions for animation states to write their own game logic code. Users can use the state machine script by inheriting from the [StateMachineScript](/apis/core/#StateMachineScript) class.
161+
162+
The state machine script provides three animation state cycles:
163+
164+
- `onStateEnter`: Callback when the animation state starts playing.
165+
- `onStateUpdate`: Callback when the animation state is updated.
166+
- `onStateExit`: Callback when the animation state ends.
167+
168+
```typescript
169+
class theScript extends StateMachineScript {
170+
// onStateEnter is called when a transition starts and the state machine starts to evaluate this state
171+
onStateEnter(animator: Animator, stateInfo: any, layerIndex: number) {
172+
console.log("onStateEnter", animator, stateInfo, layerIndex);
173+
}
174+
175+
// onStateUpdate is called on each Update frame between onStateEnter and onStateExit callbacks
176+
onStateUpdate(animator: Animator, stateInfo: any, layerIndex: number) {
177+
console.log("onStateUpdate", animator, stateInfo, layerIndex);
178+
}
179+
180+
// onStateExit is called when a transition ends and the state machine finishes evaluating this state
181+
onStateExit(animator: Animator, stateInfo: any, layerIndex: number) {
182+
console.log("onStateExit", animator, stateInfo, layerIndex);
183+
}
184+
}
185+
186+
animatorState.addStateMachineScript(theScript);
187+
```
188+
189+
If your script does not need to be reused, you can also write it like this:
190+
191+
```typescript
192+
state.addStateMachineScript(
193+
class extends StateMachineScript {
194+
onStateEnter(
195+
animator: Animator,
196+
animatorState: AnimatorState,
197+
layerIndex: number
198+
): void {
199+
console.log("onStateEnter: ", animatorState);
200+
}
201+
}
202+
);
203+
```

0 commit comments

Comments
 (0)