一.具体场景和设计初衷:
游戏里的行为树需要传许多的参数,过多的参数不好维护,也不清晰。
于是想把这些参数封装成一个类。
于是想到了Builder模式来消除这些过多的参数。
数据(参数)类 和接口
二.类图和设计:
三.具体代码:
public interface IFieldLength
{
public int FieldLengthX { get; }
public int FieldLengthY { get; }
}
public class MarchGoalNet
{
public GoalNet HomeGoalNet { get; set; }
public GoalNet AwayGoalNet { get; set; }
}
public interface IPlayersOwner
{
public PlayerBase[] GamePlayers { set; get; }
}
public class BehaviourParam
{
public bool IsInputControlled { set; get; }
public float time { set; get; }
public float deltaTime { set; get; }
public IFieldLength fieldLen { set; get; }
public MatchStatus matchStatus { set; get; }
public TeamBehaviour teamBehave { set; get; }
public float team1Density { set; get; }
public float awayOffsideLine { set; get; }
public float ourOffsideLine { set; get; }
public Ball ball { set; get; }
public MarchGoalNet GoalNets { set; get; } = new();
public IPlayersOwner teamates { set; get; }
public IPlayersOwner opponents { set; get; }
public PlayerBase Player { set; get; }
}
建造者基类
public class BehaveParamBuilder
{
protected BehaviourParam param;
private SettingBuilder setting;
private FieldInfoBuilder fieldInfo;
private MarchInfoBuilder marchInfo;
public BehaveParamBuilder()
{
param = new BehaviourParam();
}
public static BehaveParamBuilder Get()
{
return new BehaveParamBuilder();
}
public BehaviourParam Build() => param;
public SettingBuilder Setting => new(param);
public FieldInfoBuilder Field => new(param);
public MarchInfoBuilder March => new(param);
}
各个具体属性子建造者类
1.Setting类
public class SettingBuilder :BehaveParamBuilder
{
public SettingBuilder(BehaviourParam p)
{
param = p;
}
public SettingBuilder Time(float t)
{
param.time = t;
return this;
}
public SettingBuilder DeltaTime(float t)
{
param.deltaTime = t;
return this;
}
public SettingBuilder InputControll(bool isInputCtrl)
{
param.IsInputControlled = isInputCtrl;
return this;
}
}
2.Field属性的建造者类
public class FieldInfoBuilder : BehaveParamBuilder
{
public FieldInfoBuilder(BehaviourParam p)
{
param = p;
}
public FieldInfoBuilder FieldLength(IFieldLength fieldLen)
{
param.fieldLen = fieldLen;
return this;
}
public FieldInfoBuilder OurOffSideLine(float offside)
{
param.ourOffsideLine = offside;
return this;
}
public FieldInfoBuilder AwayOffSideLine(float offside)
{
param.awayOffsideLine = offside;
return this;
}
public FieldInfoBuilder FieldGoalNet(GoalNet home,GoalNet away)
{
param.GoalNets.HomeGoalNet = home;
param.GoalNets.AwayGoalNet = away;
return this;
}
public FieldInfoBuilder WithBall(Ball ball)
{
param.ball = ball;
return this;
}
}
3.March相关属性的建造者
public class MarchInfoBuilder : BehaveParamBuilder
{
public MarchInfoBuilder(BehaviourParam p)
{
param = p;
}
public MarchInfoBuilder WithMatchStatus(MatchStatus status)
{
param.matchStatus = status;
return this;
}
public MarchInfoBuilder TeamBehave(TeamBehaviour teamBehaviour)
{
param.teamBehave = teamBehaviour;
return this;
}
public MarchInfoBuilder Team1Density(float teamDensity)
{
param.team1Density = teamDensity;
return this;
}
public MarchInfoBuilder Teamates(IPlayersOwner owner)
{
param.teamates = owner;
return this;
}
public MarchInfoBuilder Opponent(IPlayersOwner owner)
{
param.opponents = owner;
return this;
}
public MarchInfoBuilder WithPlayer(PlayerBase player)
{
param.Player = player;
return this;
}
}
具体调用:
1.构造参数过程
team1Parm = new BehaveParamBuilder().Field.FieldLength(this)
.OurOffSideLine(line1X)
.AwayOffSideLine(line2X)
.FieldGoalNet(goalNet1,goalNet2)
.WithBall(ball)
.March.Opponent(GameTeam2)
.Teamates(GameTeam1)
.WithMatchStatus(MatchFlags)
.Build();
2.调用参数
BehaviourTree bt(...);
bt.OnUpdate(team1Parm)
四:总结
1.好处:避免过多的参数和过于复杂的构造器,让对象的初始化和构建过程更加清晰明了
2.缺点:需要额外的更多类去辅助某个对象的构建过程,更加复杂了。